iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 17
0

這三者一般來說可以做到一樣的事情
就是計算物件的數量
常常會讓新手(甚至是一些老手)感到好奇
到底這三者有何不同
在Ruby on Rails的領域,這個問題可以拆成兩塊
分別是Ruby的實作與Rails裡Active Record的實作

Ruby裡的length , size and count

一般在ruby階段都是在Array或Hash比較三者

Array

> a = [1,2,3]
> a.size
=> 3
> a.length
=> 3
> a.count
=> 3

特別的是
這其中只有count可以加條件,例如

> a.count{|x| x > 2 }
=> 1
> a.count 2
=> 1 #2在a裡面出現1次

但是效能上,count會差一些
size最好,但是跟length幾乎差不多

Hash

> b = {a: 1, b: 2}
> b.size
=> 2
> b.length
=> 2
> b.count
=> 2

String

有趣的是,在string裡面也可以使用這三種方法
但count的用法會不太一樣
size與length會回傳string的字串長度
但是count則需要參數,會回傳出現次數

> c = "string"
> c.size
=> 6
> c.length
=> 6
> c.count("n")
=> 1

如果只丟一個字,count是回傳出現字數
但如果超過一個字元,或是兩個或多個以上參數
其實我看不太懂String#count這個方法

> a = "hello world"
> a.count "lo"                   #=> 5
> a.count "lo", "o"              #=> 2
> a.count "hello", "^l"          #=> 4
> a.count "ej-m"                 #=> 4

看了官方範例也看不懂,所以先跳過
這不是今天的重點

Rails 的三者比較

size

比較偷懶的做法,看了原始碼更明顯

def size
  loaded? ? @records.length : count
end

如果已經載入了,就不要去撈資料庫
如果沒有,就執行count
如果有用counter catch,會直接從欄位取值

count

效能差,但是比length好
每一次都會老老實實去跑SQL讀資料庫
所以反過來說也是最準確的

>User.all.count
   (0.6ms)  SELECT COUNT(*) FROM "users"
=> 1

length

效能最差,把所有資料撈出來
只為了計算

>User.all.length
  User Load (1.2ms)  SELECT "users".* FROM "users"
=> 1

有了這些比較,是不是清楚多了呢?


上一篇
Active Record 查詢
下一篇
rails mailer preview skill
系列文
Ruby礦工的Rails地圖30

尚未有邦友留言

立即登入留言