Ruby

Ruby

By DeepSource

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

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

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
Autofix

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

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

tr/delete are more efficient than gsub.

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

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

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

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
Autofix

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

Replace methods on array with mutations RB-PR1004
Performance

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
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

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

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
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
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

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

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:

Use yield instead of block call RB-PR1015
Performance
Autofix

Use of a &block parameter and block.call can be replaced by yield in some cases.

Prefer match? over match RB-PR1018
Performance
Autofix

String#match?, Regexp#match?, and Symbol#match? are faster than match, because the methods avoid creating a MatchData object or saving backref. So, when MatchData is not used, match? can be used instead of match.