Ruby

Ruby

Made by DeepSource
Use String#end_with? instead of a regex match anchored to the end of the string RB-PR1009
Performance
Major

Instead of searching for a string pattern at the end of a string using regex, it is more efficient to simply use end_with? instead.

Do not compute the size of statically sized objects RB-PR1010
Performance
Major

Sizes of objects that we know to be static should not be computed. For example, we know the size of array in the snippet below to be 3. We can directly use the value instead of calculating it first.

Use =~ in places where the MatchData returned by #match will not be used RB-PR1016
Performance
Major
Autofix

The return value of =~ is an integral index/nil and is more performant.

Use tr/delete instead of gsub RB-PR1022
Performance
Major
Autofix

tr/delete are more efficient than gsub.

Use <= for checking inheritance instead of ancestors.include? RB-P1003
Performance
Minor

ancestors.include? can be upto 5x slower than using <= operator for checking inheritance between constants.

Use while true instead of loop RB-P1002
Performance
Minor

loop can be upto 3x times slower than using while true for unbounded loops.

rescue MethodError can be replaced with respond_to? RB-P1001
Performance
Minor

Rescuing NoMethodError can be upto 8x slower than checking for the method using respond_to?. rescue expects the exception to be raised first, hence it is much slower.

Hash merging can be replaced by hash key assignment RB-PR1017
Performance
Major

It is more efficient to replace Hash#merge! with Hash#[]=.

case..when can be modified for performance RB-PR1002
Performance
Major

Reordering when conditions with a splat to the end of the when branches can improve performance. Ruby has to allocate memory for the splat expansion every time that the case-when statement is run. Since Ruby does not support fall through inside of case-when, like some other languages do, the order of the when branches should not matter. By placing any splat expansions at the end of the list of when branches we will reduce the number of times that memory has to be allocated for the expansion. The exception to this is if multiple when conditions can be true for any given condition. A likely scenario for this is defining a higher level when condition to override a condition that is inside of the splat expansion.

Case-insensitive comparison of strings can use casecmp RB-PR1003
Performance
Major
Autofix

Case-insensitive string comparison can be done more efficiently using casecmp.

Replace methods on array with mutations RB-PR1004
Performance
Major

Methods compact, flatten and map generate a new intermediate array that is discarded. It is faster to mutate the array when we know it's safe.

Replace sort, max and min with respective _by methods RB-PR1005
Performance
Major
Autofix

sort { |a, b| a.foo <=> b.foo } can be replaced by sort_by(&:foo). This is true for max and min methods, too. All the sort, min and max methods with block in the following example can be replaced by the respective _by methods.

Use count instead of select/reject RB-PR1006
Performance
Major

Usages of count on an Enumerable that follow calls to select or reject can be made more efficient. Querying logic can instead be passed to the count call.

Use the more efficient detect method RB-PR1007
Performance
Major

Usages of select.first, select.last, find_all.first, and find_all.last can be changed to use detect instead. ActiveRecord compatibility: ActiveRecord does not implement a detect method and find has its own meaning.

Double start_with?/end_with? can be combined RB-PR1008
Performance
Major
Autofix

Double #start_with? or #end_with? calls separated by ||, in some cases, can be replaced with an single #start_with?/#end_with? call.

Use efficient method for searching hashes RB-PR1012
Performance
Major
Autofix

Hash#keys.include? is less efficient than Hash#key? because the former allocates a new array and then performs an O(n) search through that array, while Hash#key? does not allocate any array and performs a faster O(1) search for the key. Hash#values.include? is less efficient than Hash#value?. While they both perform an O(n) search through all of the values, calling values allocates a new array while using value? does not.

Consider using Struct over OpenStruct to optimize the performance RB-PR1013
Performance
Major

Instantiation of an OpenStruct invalidates Ruby global method cache as it causes dynamic method definition during program runtime. This could have an effect on performance, especially in case of single-threaded applications with multiple OpenStruct instantiations.

Use Range#cover? instead of Range#include? RB-PR1014
Performance
Major

Range#include? iterates over each item in a Range to see if a specified item is there. In contrast, Range#cover? simply compares the target item with the beginning and end points of the Range. In a great majority of cases, this is what is wanted. For example: