Issue #15251 has been updated by chopraanmol1 (Anmol Chopra).

File bench_hash_aset.rb added
Description updated

@normalperson I also benchmarked so_k_nucleotide mentioned in https://bugs.ruby-lang.org/issues/9188 with following command

~~~
benchmark-driver benchmark/so_k_nucleotide.yml -e "path_to_patched_binary" -e "path_to_trunk_binary" -e "path_to_patched_binary --jit" -e "path_to_trunk_binary --jit" --repeat-count 10
~~~ 

Result:
~~~

Calculating -------------------------------------
                     path_to_patched_binary  path_to_trunk_binary  path_to_patched_binary --jit  path_to_trunk_binary --jit 
     so_k_nucleotide                  0.786                 0.755                         0.686                       0.673 i/s -       1.000 times in 1.272604s 1.324481s 1.458204s 1.485638s

Comparison:
                  so_k_nucleotide
path_to_patched_binary:         0.8 i/s 
path_to_trunk_binary:           0.8 i/s - 1.04x  slower
path_to_patched_binary --jit:   0.7 i/s - 1.15x  slower
path_to_trunk_binary --jit:     0.7 i/s - 1.17x  slower
~~~

I think so far it looks good, let me know if I did something wrong while running the above benchmark.

----------------------------------------
Feature #15251: Hash aset should deduplicate non tainted string
https://bugs.ruby-lang.org/issues/15251#change-74607

* Author: chopraanmol1 (Anmol Chopra)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
I'm not sure if current behavior is expected one or a bug. So feel free to change tracker type.

Currently Hash ASET checks if non-tainted string exists in fstring table or not, if it doesn't then ruby duplicates string and freeze it. This works well for string_literal because they are already registered in fstring table, but it doesn't work for non-literal string.

Patch

https://github.com/ruby/ruby/pull/1993

O/P of attached file(test_hash_keys_deduped.rb) on trunk:
~~~
string_literal => 1
string times 1 => 1
string times 3 string times 3 string times 3  => 100
interpolated_string => 100
string add => 100
string append => 100
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
fstring
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
string_literal => 1
string times 1 => 1
string times 3 string times 3 string times 3  => 1
interpolated_string => 1
string add => 1
string append => 1
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
fstring + GC
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
string_literal => 1
string times 1 => 1
string times 3 string times 3 string times 3  => 100
interpolated_string => 100
string add => 100
string append => 100
~~~

after patch
~~~
string_literal => 1
string times 1 => 1
string times 3 string times 3 string times 3  => 1
interpolated_string => 1
string add => 1
string append => 1
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
fstring
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
string_literal => 1
string times 1 => 1
string times 3 string times 3 string times 3  => 1
interpolated_string => 1
string add => 1
string append => 1
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
fstring + GC
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
string_literal => 1
string times 1 => 1
string times 3 string times 3 string times 3  => 1
interpolated_string => 1
string add => 1
string append => 1
~~~

Benchmark result(bench_hash_aset.rb):
Trunk:
~~~
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hash#[`string literal`.dup]=
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  0.880000   0.000000   0.880000 (  0.880699)
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hash#[`string non-literal`.dup]=
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  0.980000   0.000000   0.980000 (  0.978089)
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hash#[`random text`]=
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  3.716000   0.004000   3.720000 (  3.722688)
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hash#[`string literal`.dup]=
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  0.868000   0.000000   0.868000 (  0.868405)
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hash#[`string non-literal`.dup]=
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  0.948000   0.000000   0.948000 (  0.948946)
~~~

Patched:
~~~
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hash#[`string literal`.dup]=
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  0.872000   0.000000   0.872000 (  0.872410)
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hash#[`string non-literal`.dup]=
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  0.864000   0.000000   0.864000 (  0.865356)
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hash#[`random text`]=
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  3.780000   0.000000   3.780000 (  3.779730)
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hash#[`string literal`.dup]=
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  0.868000   0.000000   0.868000 (  0.867957)
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hash#[`string non-literal`.dup]=
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  0.872000   0.000000   0.872000 (  0.873573)
~~~


---Files--------------------------------
test_hash_keys_deduped.rb (927 Bytes)
bench_hash_aset.rb (1.35 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>