summaryrefslogtreecommitdiff
path: root/benchmark
diff options
context:
space:
mode:
authorDylan Thacker-Smith <dylan.smith@shopify.com>2019-10-21 04:29:21 -0400
committerKoichi Sasada <ko1@atdot.net>2019-10-21 17:29:21 +0900
commitb9702590445dfea62d271d0a5c942b7adfaaacdd (patch)
tree852a7ab275be68f9cd219c6e07b5689981bc4028 /benchmark
parent8b8b9c1a1fdb26f9b0470391234d8c935b083577 (diff)
Stop making a redundant hash copy in Hash#dup (#2489)
* Stop making a redundant hash copy in Hash#dup It was making a copy of the hash without rehashing, then created an extra copy of the hash to do the rehashing. Since rehashing creates a new copy already, this change just uses that rehashing to make the copy. [Bug #16121] * Remove redundant Check_Type after to_hash * Fix freeing and clearing destination hash in Hash#initialize_copy The code was assuming the state of the destination hash based on the source hash for clearing any existing table on it. If these don't match, then that can cause the old table to be leaked. This can be seen by compiling hash.c with `#define HASH_DEBUG 1` and running the following script, which will crash from a debug assertion. ```ruby h = 9.times.map { |i| [i, i] }.to_h h.send(:initialize_copy, {}) ``` * Remove dead code paths in rb_hash_initialize_copy Given that `RHASH_ST_TABLE_P(h)` is defined as `(!RHASH_AR_TABLE_P(h))` it shouldn't be possible for a hash to be neither of these, so there is no need for the removed `else if` blocks. * Share implementation between Hash#replace and Hash#initialize_copy This also fixes key rehashing for small hashes backed by an array table for Hash#replace. This used to be done consistently in ruby 2.5.x, but stopped being done for small arrays in ruby 2.6.x. This also bring optimization improvements that were done for Hash#initialize_copy to Hash#replace. * Add the Hash#dup benchmark
Diffstat (limited to 'benchmark')
-rw-r--r--benchmark/hash_dup.yml8
1 files changed, 8 insertions, 0 deletions
diff --git a/benchmark/hash_dup.yml b/benchmark/hash_dup.yml
new file mode 100644
index 0000000000..65f521ec94
--- /dev/null
+++ b/benchmark/hash_dup.yml
@@ -0,0 +1,8 @@
+prelude: |
+ small_hash = { a: 1 }
+ larger_hash = 20.times.map { |i| [('a'.ord + i).chr.to_sym, i] }.to_h
+
+benchmark:
+ dup_small: small_hash.dup
+ dup_larger: larger_hash.dup
+loop_count: 10000