Tổng hợp các cách tối ưu code Ruby on Rails hiệu quả - P1
Bài đăng này đã không được cập nhật trong 3 năm
Trong quá trình phát triển web với Ruby on Rails, mình nhận ra khía cạnh optimize code trong rails là rất quan trọng, bởi vì để web được viết bởi rails chạy nhanh hơn, và người sử dụng có một trải nghiệm tốt hơn, chúng ta chắc chắn phải tối ưu code của mình. Bài viết này với mục đích tổng hợp các cách tối ưu hóa code Ruby on Rails mà các bạn có thể áp dụng với tất cả dự án từ lớn đến nhỏ.
1. Tối ưu hóa code Ruby
Bởi vì Ruby on rails được xây dựng từ Ruby nên đế tối ưu hóa Rails app thì bước đầu tiên đó là ta phải tối ưu code Ruby.
- Mọi thứ trong Ruby là Object, ví dụ để xử lý 1Gb data trong ruby thì cần rất nhiều bộ nhớ cho nên ta có thể tối ưu bằng cách giảm thiểu sử dụng code Ruby nếu cần thiết, chẳng hạn như:
a. Đối với các rails app sử dụng view ERB thuần, ta có thể lược bỏ các code Ruby được sử dụng trong ERB nếu như không thực sự cần thiết:
Ví dụ: với helpers link_to dùng để tạo ra hyperlink như sau:
<%= link_to t('users.your_profile'), users_kimochi_path %>
-> ta có thể viết lại tương đương:
<a href="<%= users_kimochi_path %>"><%= t 'users.your_profile' %></a>
b. Hiểu rõ cách sử dụng các method như nil, blank, empty Đây là một lỗi rất hay mắc phải bởi các bạn dev Ruby, bởi đơn giản là các bạn hay sử dụng lẫn lộn do không nhớ rõ ý nghĩa của từng method. So sánh tốc độ khi sử dụng từng method:
empty String :empty?
# 4.604020118713379e-07
non_empty String :empty?
# 4.5903921127319333e-07
Object :nil?
# 5.041143894195557e-07
NilClass :nil?
# 4.7951340675354e-07
FalseClass, NilClass, TrueClass :blank?
# 4.09862756729126e-07
main :blank? ( respond_to returns false )
# 6.444177627563477e-07
Array :blank? ( respond_to returns true )
# 6.491720676422119e-07
String :blank?
# 1.4315705299377442e-06
Như có thể thấy, blank
thì nên sử dụng với string
, còn Object
thì nên sử dụng với empty?
, nil
thì nên sử dụng với NilClass
Dưới đây là bảng sử dụng cho từng method cụ thể:
c. Sử dụng Symbol hơn là String trong so sánh
Chẳng hạn:
good_stuff = "good" #khởi tạo
puts "Ah, kimochi!" if good_stuff == "good" #khởi tạo
puts "Yamate!" if good_stuff == "bad" #khởi tạo
ở đây ta sử dụng string "good" 2 lần, "bad" 1 lần, tức là ta đã tạo thêm các object riêng lẻ. Tuy nhiên sử dụng symbol thì chỉ khởi tạo chúng một lần và sử dụng lại, điều này sẽ giúp tiết kiệm bộ nhớ:
good_stuff = :good #khởi tạo
puts "Ah, kimochi!" if good_stuff == :good #dùng lại :good
puts "Yamate!" if good_stuff == :bad #khởi tạo
d. Hiểu rõ cách sử dụng present, any, exists Đa phần các dev Ruby sẽ sử dụng method present để check điều kiện có tồn tại hay không, tuy nhiên sẽ đưa đến tốc độ thực thi rất chậm. Bảng so sánh tốc độ:
exists?: 158.4 i/s
any?: 10.1 i/s - 15.65x slower
present?: 2.3 i/s - 68.39x slower
Link thảm khảo: https://goo.gl/NbFhms
e. Dùng đúng iterators Sử dụng vòng lặp trong rails là một phần không thể thiếu, tuy nhiên không phải lúc nào cũng nên dùng each
user system total real
each 4.540000 0.000000 4.540000 ( 4.532571)
for ... in 4.730000 0.010000 4.740000 ( 4.738334)
for ... in 0..limit 5.380000 0.000000 5.380000 ( 5.370768)
while i <ARRAY.size 3.050000 0.000000 3.050000 ( 3.058212)
while i <limit 2.710000 0.010000 2.720000 ( 2.704505)
Link thảm khảo: https://goo.gl/PN6Rzt
f. Sử dụng đúng length, size, count với Array Sử dụng length so với size hoặc count với Array sẽ cho tốc độ tốt hơn
Array#length: 11394036.7 i/s
Array#size: 11302701.1 i/s - 1.01x slower
Array#count: 9194976.2 i/s - 1.24x slower
g. Sử dụng Struct thay vì hash nếu có thể
student = Struct.new(:name, :address, :class)
# truy cập nhanh hơn
student.new('abc', '123 nct', '12345')
# truy cập chậm hơn với hash
{name: 'abc', address: '123 nct', class: '12345'}
Link tham khảo: http://ruby-doc.org/core-2.4.2/Struct.html
h. Sử dụng nối string một cách tối ưu
Khi bạn sử dụng dấu +
để nối chuỗi thì sẽ tạo ra các object mới vì trong ruby ngay cả chuỗi cũng là các object. Thay vào đó ta có thể sử dụng phương pháp interpolation hoặc dùng nối chuỗi với <<, sẽ tối ưu code hơn.
string interpolation (#{}) 0.280000 0.000000 0.280000 ( 0.278142)
string concatenation ( << ) 0.300000 0.000000 0.300000 ( 0.307941)
string addition ( + ) 0.340000 0.000000 0.340000 ( 0.345992)
(còn tiếp)
All rights reserved