[前][次][番号順一覧][スレッド一覧]

ruby-changes:47628

From: shyouhei <ko1@a...>
Date: Tue, 5 Sep 2017 13:48:23 +0900 (JST)
Subject: [ruby-changes:47628] shyouhei:r59744 (trunk): add rb_hash_new_with_size()

shyouhei	2017-09-05 13:48:19 +0900 (Tue, 05 Sep 2017)

  New Revision: 59744

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59744

  Log:
    add rb_hash_new_with_size()
    
    Sometimes, size of a hash can be calcluated a priori.  By providing
    such info to the constructor we can avoid unnecessary internal re-
    allocations.  This can boost for instance creation of hash literals.
    [Bug #13861]
    
    Signed-off-by: Urabe, Shyouhei <shyouhei@r...>

  Modified files:
    trunk/hash.c
    trunk/insns.def
    trunk/internal.h
    trunk/vm.c
Index: internal.h
===================================================================
--- internal.h	(revision 59743)
+++ internal.h	(revision 59744)
@@ -1242,6 +1242,7 @@ void ruby_sized_xfree(void *x, size_t si https://github.com/ruby/ruby/blob/trunk/internal.h#L1242
 
 /* hash.c */
 struct st_table *rb_hash_tbl_raw(VALUE hash);
+VALUE rb_hash_new_with_size(st_index_t size);
 VALUE rb_hash_has_key(VALUE hash, VALUE key);
 VALUE rb_hash_default_value(VALUE hash, VALUE key);
 VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
Index: vm.c
===================================================================
--- vm.c	(revision 59743)
+++ vm.c	(revision 59744)
@@ -2694,7 +2694,7 @@ m_core_hash_from_ary(VALUE self, VALUE a https://github.com/ruby/ruby/blob/trunk/vm.c#L2694
 static VALUE
 core_hash_from_ary(VALUE ary)
 {
-    VALUE hash = rb_hash_new();
+    VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary) / 2);
 
     RUBY_DTRACE_CREATE_HOOK(HASH, (Check_Type(ary, T_ARRAY), RARRAY_LEN(ary)));
     return core_hash_merge_ary(hash, ary);
Index: hash.c
===================================================================
--- hash.c	(revision 59743)
+++ hash.c	(revision 59744)
@@ -432,6 +432,15 @@ rb_hash_new(void) https://github.com/ruby/ruby/blob/trunk/hash.c#L432
     return hash_alloc(rb_cHash);
 }
 
+VALUE
+rb_hash_new_with_size(st_index_t size)
+{
+    VALUE ret = rb_hash_new();
+    if (size)
+        RHASH(ret)->ntbl = st_init_table_with_size(&objhash, size);
+    return ret;
+}
+
 static VALUE
 hash_dup(VALUE hash, VALUE klass, VALUE flags)
 {
@@ -1927,7 +1936,7 @@ rb_hash_transform_values(VALUE hash) https://github.com/ruby/ruby/blob/trunk/hash.c#L1936
     VALUE result;
 
     RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
-    result = rb_hash_new();
+    result = rb_hash_new_with_size(RHASH_SIZE(hash));
     if (!RHASH_EMPTY_P(hash)) {
         rb_hash_foreach(hash, transform_values_i, result);
     }
Index: insns.def
===================================================================
--- insns.def	(revision 59743)
+++ insns.def	(revision 59744)
@@ -496,7 +496,7 @@ newhash https://github.com/ruby/ruby/blob/trunk/insns.def#L496
 {
     RUBY_DTRACE_CREATE_HOOK(HASH, num);
 
-    val = rb_hash_new();
+    val = rb_hash_new_with_size(num / 2);
 
     if (num) {
         rb_hash_bulk_insert(num, STACK_ADDR_FROM_TOP(num), val);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]