summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-04-21 04:21:14 +0000
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-04-21 04:21:14 +0000
commit4ee09d914db903cb6f4cf50c4bb03c163694b465 (patch)
treec66b92a237f70abb15d61124f4c685848fba6f72 /vm.c
parentbdc6d41640f07d260b66eaaeea38145789227513 (diff)
refactor hash literal
Same as rb_ary_tmp_new_from_values(), it reduces vm_exec_core binary size from 26,176 bytes to 26,080 bytes. But this time, also with a bit of optimizations: - Because we are allocating a new hash and no back references are introduced at all, we can safely skip write barriers. - Also, the iteration never recurs. We can avoid complicated function callbacks by using st_insert instead of st_update. ---- * hash.c (rb_hash_new_from_values): refactor extract the bulk insert into a function. * hash.c (rb_hash_new_from_object): also refactor. * hash.c (rb_hash_s_create): use the new functions. * insns.def (newhash): ditto. * vm.c (core_hash_from_ary): ditto. * iternal.h: export the new function. ----------------------------------------------------------- benchmark results: minimum results in each 7 measurements. Execution time (sec) name before after loop_whileloop2 0.135 0.134 vm2_bighash* 1.236 0.687 Speedup ratio: compare with the result of `before' (greater is better) name after loop_whileloop2 1.008 vm2_bighash* 1.798 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58427 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c31
1 files changed, 10 insertions, 21 deletions
diff --git a/vm.c b/vm.c
index e64c072fdc..968f2dbf3e 100644
--- a/vm.c
+++ b/vm.c
@@ -2646,7 +2646,6 @@ m_core_set_postexe(VALUE self)
return Qnil;
}
-static VALUE core_hash_merge_ary(VALUE hash, VALUE ary);
static VALUE core_hash_from_ary(VALUE ary);
static VALUE core_hash_merge_kwd(int argc, VALUE *argv);
@@ -2656,7 +2655,6 @@ core_hash_merge(VALUE hash, long argc, const VALUE *argv)
long i;
Check_Type(hash, T_HASH);
- VM_ASSERT(argc % 2 == 0);
for (i=0; i<argc; i+=2) {
rb_hash_aset(hash, argv[i], argv[i+1]);
}
@@ -2674,27 +2672,18 @@ m_core_hash_from_ary(VALUE self, VALUE ary)
static VALUE
core_hash_from_ary(VALUE ary)
{
- VALUE hash = rb_hash_new();
+ long n;
- RUBY_DTRACE_CREATE_HOOK(HASH, (Check_Type(ary, T_ARRAY), RARRAY_LEN(ary)));
- return core_hash_merge_ary(hash, ary);
-}
-
-#if 0
-static VALUE
-m_core_hash_merge_ary(VALUE self, VALUE hash, VALUE ary)
-{
- REWIND_CFP(core_hash_merge_ary(hash, ary));
- return hash;
-}
-#endif
-
-static VALUE
-core_hash_merge_ary(VALUE hash, VALUE ary)
-{
Check_Type(ary, T_ARRAY);
- core_hash_merge(hash, RARRAY_LEN(ary), RARRAY_CONST_PTR(ary));
- return hash;
+ n = RARRAY_LEN(ary);
+ RUBY_DTRACE_CREATE_HOOK(HASH, n);
+ if (n) {
+ VM_ASSERT(n % 2 == 0);
+ return rb_hash_new_from_values(n, RARRAY_PTR(ary));
+ }
+ else {
+ return rb_hash_new();
+ }
}
static VALUE