Skip to content

Commit

Permalink
Hash#update() vs Hash#[]=
Browse files Browse the repository at this point in the history
  • Loading branch information
Manjunath committed Aug 6, 2021
1 parent eff12ff commit dc7a28c
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 0 deletions.
1 change: 1 addition & 0 deletions .fasterer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ speedups:
fetch_with_argument_vs_block: true
keys_each_vs_each_key: true
hash_merge_bang_vs_hash_brackets: true
hash_update_vs_hash_brackets: true
block_vs_symbol_to_proc: true
proc_call_vs_yield: true
gsub_vs_tr: true
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ speedups:
fetch_with_argument_vs_block: true
keys_each_vs_each_key: true
hash_merge_bang_vs_hash_brackets: true
hash_update_vs_hash_brackets: true
block_vs_symbol_to_proc: true
proc_call_vs_yield: true
gsub_vs_tr: true
Expand Down
3 changes: 3 additions & 0 deletions lib/fasterer/offense.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ def explanation
hash_merge_bang_vs_hash_brackets:
'Hash#merge! with one argument is slower than Hash#[]',

hash_update_vs_hash_brackets:
'Hash#update with one argument is slower than Hash#[]',

block_vs_symbol_to_proc:
'Calling argumentless methods within blocks is slower than using symbol to proc',

Expand Down
13 changes: 13 additions & 0 deletions lib/fasterer/scanners/method_call_scanner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ def check_offense
check_fetch_offense
when :merge!
check_merge_bang_offense
when :update
check_update_offense
when :last
check_last_offense
when :include?
Expand Down Expand Up @@ -149,6 +151,17 @@ def check_merge_bang_offense
end
end

def check_update_offense
return unless method_call.arguments.count == 1

first_argument = method_call.arguments.first
return unless first_argument.type == :hash

if first_argument.element.drop(1).count == 2 # each key and value is an item by itself.
add_offense(:hash_update_vs_hash_brackets)
end
end

def check_last_offense
return method_call unless method_call.receiver.is_a?(MethodCall)

Expand Down
11 changes: 11 additions & 0 deletions spec/lib/fasterer/analyzer/17_hash_update_vs_hash_brackets_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require 'spec_helper'

describe Fasterer::Analyzer do
let(:test_file_path) { RSpec.root.join('support', 'analyzer', '17_hash_update_vs_hash_brackets.rb') }

it 'should detect keys each 3 times' do
analyzer = Fasterer::Analyzer.new(test_file_path)
analyzer.scan
expect(analyzer.errors[:hash_update_vs_hash_brackets].count).to eq(3)
end
end
21 changes: 21 additions & 0 deletions spec/support/analyzer/17_hash_update_vs_hash_brackets.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
h.update(item: 1, item2: 3)

h.update

h.update(item, item: 1)

h.update(item: 1)

ENUM.each_with_object({}) do |e, h|
h.update(e => e)
end

ENUM.each_with_object({}) do |e, h|
h[e] = e
end

h.update(item: 1)

h.update({item: 1})

h.update({})

0 comments on commit dc7a28c

Please sign in to comment.