Ruby offers a lot of great features for manipulating data. If we aren’t careful though, it’s easy to write code that consumes more memory and CPU time than we would expect. Here’s a tip on optimizing Ruby code for better performance.
Consider this locale detection code:
string = params[:country] country = COUNTRY_CODE_MAP.detect do |k,v| [k.downcase, v.downcase].include? string.downcase end
Although it reads nicely, this code has several performance issues:
downcasecreates copies of the strings.
The return value of
downcaseis a copy of the string with all the characters converted to lower case.
includeforces both upper and lower cases to be evaluated.
With a few simple modifications we can greatly reduce the number of operations and new variables used:
string = params[:country] country = COUNTRY_CODE_MAP.detect do |k,v| k.casecmp(string) == 0 || v.casecmp(string) == 0 end
In the refactored code we:
- Don’t create a new array on every iteration.
- Don’t copy the strings by not using
- Only compare to v if k doesn’t match.
Although these differences may seem small on the surface, remember that this code may get run millions of times a day. Also, your collections may grow to sizes that you never imagined! It’s small changes like these that will make huge differences at scale.
Share your tips for optimizing Ruby code for better performanceOptim in the comments below.