Skip to content

Commit

Permalink
Optimize duplicate hash key warning
Browse files Browse the repository at this point in the history
- Replaces O(n^2) processing loop with a set. I benchmarked parsing a file with a single 5000 key hash to test this change's performance. Before:

**Before**

```sh
$ hyperfine --warmup 3 'bin/ruby-parse hash_bench.rb'

Benchmark 1: bin/ruby-parse hash_bench.rb
  Time (mean ± σ):      2.678 s ±  0.029 s    [User: 2.613 s, System: 0.061 s]
  Range (min … max):    2.636 s …  2.738 s    10 runs
```

**After**

```sh
$ hyperfine --warmup 3 'bin/ruby-parse hash_bench.rb'

Benchmark 1: bin/ruby-parse hash_bench.rb
  Time (mean ± σ):     421.3 ms ±   4.1 ms    [User: 366.9 ms, System: 49.9 ms]
  Range (min … max):   414.8 ms … 426.1 ms    10 runs
```

- See whitequark#918
  • Loading branch information
dgollahon committed Apr 15, 2023
1 parent f1da317 commit e406ecf
Showing 1 changed file with 13 additions and 24 deletions.
37 changes: 13 additions & 24 deletions lib/parser/builders/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -538,34 +538,23 @@ def kwsplat(dstar_t, arg)
end

def associate(begin_t, pairs, end_t)
0.upto(pairs.length - 1) do |i|
(i + 1).upto(pairs.length - 1) do |j|
pair_i = pairs[i]
pair_j = pairs[j]
key_set = Set.new

next if pair_i.type != :pair || pair_j.type != :pair
pairs.each do |pair|
next unless pair.type.eql?(:pair)

key1, = *pair_i
key2, = *pair_j
key, = *pair

do_warn = false

# keys have to be simple nodes, MRI ignores equal composite keys like
# `{ a(1) => 1, a(1) => 1 }`
case key1.type
when :sym, :str, :int, :float
if key1 == key2
do_warn = true
end
when :rational, :complex, :regexp
if @parser.version >= 31 && key1 == key2
do_warn = true
end
end
case key.type
when :sym, :str, :int, :float
when :rational, :complex, :regexp
next unless @parser.version >= 31
else
next
end

if do_warn
diagnostic :warning, :duplicate_hash_key, nil, key2.loc.expression
end
unless key_set.add?(key)
diagnostic :warning, :duplicate_hash_key, nil, key.loc.expression
end
end

Expand Down

0 comments on commit e406ecf

Please sign in to comment.