Usage of push operator over overload operator
Avoid the usage of overload addition (+=) ruby operator. Instead, replace it with the push operator (<<) for strings and arrays.
Correct usage of bang methods
Usage of In-Place updates (destructive operations) selectively to save copying overhead.
Unlike the Rails bang methods, the Ruby bang methods perform an action and change the object. They return the modified object as a result. This is object mutation, so they are often termed as mutator/dangerous methods.
Usage condition - If the original object is not required multiple times in the codebase, then Ruby destructive methods can be used, instead of their simple copying counterparts.
Class | Copying | Destructive |
---|
String | #+ | #<< |
String | #sub | #sub! |
String | #gsub | #gsub! |
Hash | #merge | #merge! |
Array | #+ | #concat |
Array | #map | #map! |
Array | #compact | #compact! |
Array | #uniq | #uniq! |
Array | #flatten | #flatten! |
Here are the use cases:
Where altering original variable content does not affect the logic
Refrain usage where altering original variable content affects the logic
Avoid comparison of BigDecimal with integer or string
Usage of String Interpolation instead of + operator
Correct usage of reader and accessors
Apply reader and accessors correctly, based on usage within or outside the class.
Here are the use cases:
Redundant usage of attr_accessors although setters are not used within/outside class.
Usage of Instance variable instead of accessors, when public method access is not required
Optimize usage of constants
Optimize access to Global constants through usage of namespace operator ::
in front of constant.
Usage of constant declaration for temporary data structures
Use constant declaration for temporary data structures like Array, which are not going to be changed overtime.
Usage of blocks instead of Symbol.to_proc
Order under different cases
- Most frequent case should be added first
- If all cases are equally frequent, prefer sorting in the increasing order of computation
Avoid operations which clear Ruby's method cache
Dynamic language implementations use 'inline method caching', which avoid expensive method lookups frequently. But some of the below given methods invalidate the method caching. Avoiding them at runtime is critical to writing fast Ruby code.
- Aliasing or removing methods (Module#alias_method and Module#remove_method): Aliasing and removing methods invalidates the method caches
- Setting and removing constants (#const_set and #remove_const)
- Changing constant visibility (Module#private_constant and Module#public_constant)
- Module including, prepending and extending and Object#extend
Prefer #include over #extend for better performance
- Marshal loading an extended object (Marshal.load)
- Garbage collecting a class or module (GS.start)
Here is a use case:
Redundant define_method
usage when they are non-runtime dependent method definitions and can be declared before-hand.
Cache data in variables
Cache Data in Instance Variables
Cache Data in Class Variables for large persisting data
Usage of constants to store database results to avoid hitting db frequently
Usage of ActiveSupport::Memoizable for memoization of expensive operations
Initialize variable with nil
Instance variables already default to nil.
Usage of conditionals directly in place of .nil?
Avoid method overhead call by directly using if user
instead of if user.nil?
Based on user-to-user preference over unless vs if readability following changes can be done
Usage of blank? in place of empty? or nil?
Since blank? checks for both cases of value to be nil or empty, it's better to use blank? in such cases.
Set over Array
Preference of Set over Array for search (include?) and cluster operations (uniq, |, &)
Avoid repeated Hash access
Extend classes vs reopen classes vs mixin usage
Extending a class is slower compared to opening the class or using mix-in.
Freeze constant data
Constant data including arrays and hashes, should be frozen if they are accessed but not mutated in the codebase.
All strings will already be frozen by rubocop, so freezing them is not required.