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

 
1
From eaaf0b89553a9f61ea30dfff90f667092c7115ac Mon Sep 17 00:00:00 2001
2
From: Dylan Thacker-Smith <Dylan.Smith@shopify.com>
3
Date: Fri, 23 Aug 2019 00:48:06 -0400
4
Subject: [PATCH 4/4] Stop making a redundant hash copy in Hash#dup
5

    
6
It was making a copy of the hash without rehashing, then created an
7
extra copy of the hash to do the rehashing.  Since rehashing creates
8
a new copy already, this change just uses that rehashing to make
9
the copy.
10
---
11
 hash.c | 14 +++++---------
12
 1 file changed, 5 insertions(+), 9 deletions(-)
13

    
14
diff --git a/hash.c b/hash.c
15
index aeddf44d34..08c2c97505 100644
16
--- a/hash.c
17
+++ b/hash.c
18
@@ -2800,18 +2800,14 @@ rb_hash_initialize_copy(VALUE hash, VALUE hash2)
19
         ar_free_and_clear_table(hash);
20
     }
21
 
22
-    if (RHASH_AR_TABLE_P(hash2)) {
23
-        ar_copy(hash, hash2);
24
-        if (RHASH_AR_TABLE_SIZE(hash))
25
-	    rb_hash_rehash(hash);
26
-    }
27
-    else {
28
-        RHASH_ST_TABLE_SET(hash, st_copy(RHASH_ST_TABLE(hash2)));
29
-        if (RHASH_ST_TABLE(hash)->num_entries)
30
-            rb_hash_rehash(hash);
31
+    unsigned long size = RHASH_SIZE(hash2);
32
+    if (size > RHASH_AR_TABLE_MAX_SIZE) {
33
+        RHASH_ST_TABLE_SET(hash, st_init_table_with_size(&objhash, size));
34
     }
35
 
36
+    rb_hash_foreach(hash2, rb_hash_rehash_i, (VALUE)hash);
37
     COPY_DEFAULT(hash, hash2);
38
+    rb_gc_writebarrier_remember(hash);
39
 
40
     return hash;
41
 }
42
-- 
43
2.21.0
44