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

ruby-changes:39329

From: normal <ko1@a...>
Date: Tue, 28 Jul 2015 07:27:32 +0900 (JST)
Subject: [ruby-changes:39329] normal:r51410 (trunk): symbol.h: memoize hashval for RSymbol

normal	2015-07-28 07:25:30 +0900 (Tue, 28 Jul 2015)

  New Revision: 51410

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

  Log:
    symbol.h: memoize hashval for RSymbol
    
    This speeds up the hash function for dynamic symbols.
    [ruby-core:70129] [Bug #11396], nearly up to Ruby 2.1 levels
    
    Power-of-two hash sizing [Feature #9425] speeds up cases where we
    have a good hash, but this means we can no longer hide behind weak
    hashes.  Unfortunately, object IDs do not hash well, but we may
    use the extra space in the RSymbol struct to memoize the hash value.
    
    Further optimizations should be possible.  For now, the st.c APIs
    force us to calculate rb_str_hash redundantly at dsym registration.
    
    * symbol.h (struct RSymbol): add hashval field
    * symbol.c (dsymbol_alloc): setup hashval field once
    * hash.c (rb_any_hash): return RSymbol->hashval directly
    * common.mk: hash.o depends on symbol.h
      Thanks to Bruno Escherl <bruno@e...> for the bug report
      [ruby-core:70129] [Bug #11396]

  Modified files:
    trunk/ChangeLog
    trunk/common.mk
    trunk/hash.c
    trunk/symbol.c
    trunk/symbol.h
Index: symbol.c
===================================================================
--- symbol.c	(revision 51409)
+++ symbol.c	(revision 51410)
@@ -505,12 +505,18 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/symbol.c#L505
 dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding * const enc, const ID type)
 {
     const VALUE dsym = rb_newobj_of(klass, T_SYMBOL | FL_WB_PROTECTED);
+    st_index_t hashval;
 
     rb_enc_associate(dsym, enc);
     OBJ_FREEZE(dsym);
     RB_OBJ_WRITE(dsym, &RSYMBOL(dsym)->fstr, str);
     RSYMBOL(dsym)->id = type;
 
+    /* we want hashval to be in Fixnum range [ruby-core:15713] r15672 */
+    hashval = rb_str_hash(str);
+    hashval <<= 1;
+    RSYMBOL(dsym)->hashval = (st_index_t)RSHIFT(hashval, 1);
+
     register_sym(str, dsym);
     rb_hash_aset(global_symbols.dsymbol_fstr_hash, str, Qtrue);
 
Index: symbol.h
===================================================================
--- symbol.h	(revision 51409)
+++ symbol.h	(revision 51410)
@@ -25,6 +25,7 @@ https://github.com/ruby/ruby/blob/trunk/symbol.h#L25
 
 struct RSymbol {
     struct RBasic basic;
+    st_index_t hashval;
     VALUE fstr;
     ID id;
 };
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 51409)
+++ ChangeLog	(revision 51410)
@@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Jul 28 07:23:03 2015  Eric Wong  <e@8...>
+
+	* symbol.h (struct RSymbol): add hashval field
+	* symbol.c (dsymbol_alloc): setup hashval field once
+	* hash.c (rb_any_hash): return RSymbol->hashval directly
+	* common.mk: hash.o depends on symbol.h
+	  Thanks to Bruno Escherl <bruno@e...> for the bug report
+	  [ruby-core:70129] [Bug #11396]
+
 Tue Jul 28 03:26:15 2015  Aaron Patterson <tenderlove@r...>
 
 	* ext/openssl/lib/openssl/ssl.rb (module OpenSSL): raise a more
Index: common.mk
===================================================================
--- common.mk	(revision 51409)
+++ common.mk	(revision 51410)
@@ -1532,6 +1532,7 @@ hash.$(OBJEXT): {$(VPATH)}oniguruma.h https://github.com/ruby/ruby/blob/trunk/common.mk#L1532
 hash.$(OBJEXT): {$(VPATH)}probes.h
 hash.$(OBJEXT): {$(VPATH)}st.h
 hash.$(OBJEXT): {$(VPATH)}subst.h
+hash.$(OBJEXT): {$(VPATH)}symbol.h
 hash.$(OBJEXT): {$(VPATH)}util.h
 hash.$(OBJEXT): {$(VPATH)}vm_opts.h
 inits.$(OBJEXT): $(hdrdir)/ruby/ruby.h
Index: hash.c
===================================================================
--- hash.c	(revision 51409)
+++ hash.c	(revision 51410)
@@ -17,6 +17,7 @@ https://github.com/ruby/ruby/blob/trunk/hash.c#L17
 #include <errno.h>
 #include "probes.h"
 #include "id.h"
+#include "symbol.h"
 
 #ifdef __APPLE__
 # ifdef HAVE_CRT_EXTERNS_H
@@ -149,7 +150,7 @@ rb_any_hash(VALUE a) https://github.com/ruby/ruby/blob/trunk/hash.c#L150
 	hnum = rb_str_hash(a);
     }
     else if (BUILTIN_TYPE(a) == T_SYMBOL) {
-	hnum = rb_objid_hash((st_index_t)a);
+	return RSYMBOL(a)->hashval;
     }
     else if (BUILTIN_TYPE(a) == T_FLOAT) {
 	return rb_dbl_hash(rb_float_value(a));

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

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