Project

General

Profile

Bug #16121 » 0004-Stop-making-a-redundant-hash-copy-in-Hash-dup.diff.txt

[PATCH 4/4] Stop making a redundant hash copy in Hash#dup - dylants (Dylan Thacker-Smith), 08/23/2019 07:55 PM

 
From eaaf0b89553a9f61ea30dfff90f667092c7115ac Mon Sep 17 00:00:00 2001
From: Dylan Thacker-Smith <Dylan.Smith@shopify.com>
Date: Fri, 23 Aug 2019 00:48:06 -0400
Subject: [PATCH 4/4] 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.
---
hash.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/hash.c b/hash.c
index aeddf44d34..08c2c97505 100644
--- a/hash.c
+++ b/hash.c
@@ -2800,18 +2800,14 @@ rb_hash_initialize_copy(VALUE hash, VALUE hash2)
ar_free_and_clear_table(hash);
}
- if (RHASH_AR_TABLE_P(hash2)) {
- ar_copy(hash, hash2);
- if (RHASH_AR_TABLE_SIZE(hash))
- rb_hash_rehash(hash);
- }
- else {
- RHASH_ST_TABLE_SET(hash, st_copy(RHASH_ST_TABLE(hash2)));
- if (RHASH_ST_TABLE(hash)->num_entries)
- rb_hash_rehash(hash);
+ unsigned long size = RHASH_SIZE(hash2);
+ if (size > RHASH_AR_TABLE_MAX_SIZE) {
+ RHASH_ST_TABLE_SET(hash, st_init_table_with_size(&objhash, size));
}
+ rb_hash_foreach(hash2, rb_hash_rehash_i, (VALUE)hash);
COPY_DEFAULT(hash, hash2);
+ rb_gc_writebarrier_remember(hash);
return hash;
}
--
2.21.0

(4-4/4)