From 852caed8a375ba761a786fc6c3d0da644422434f Mon Sep 17 00:00:00 2001 From: glass Date: Thu, 18 Jul 2013 08:48:12 +0000 Subject: [PATCH] * hash.c (rb_hash_flatten): performance improvement by not using rb_hash_to_a() to avoid array creation with rb_assoc_new(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42039 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ hash.c | 28 +++++++++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 534775a1db..ab67c8a78c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Thu Jul 18 17:35:41 2013 Masaki Matsushita + + * hash.c (rb_hash_flatten): performance improvement by not using + rb_hash_to_a() to avoid array creation with rb_assoc_new(). + Thu Jul 18 16:16:17 2013 Koichi Sasada * array.c: add logging feature for RGenGC's write barrier unprotect diff --git a/hash.c b/hash.c index 2cdf8b2dbf..447d73feb1 100644 --- a/hash.c +++ b/hash.c @@ -2187,6 +2187,18 @@ rb_hash_rassoc(VALUE hash, VALUE obj) return args[1]; } +static int +flatten_i(VALUE key, VALUE val, VALUE ary) +{ + VALUE pair[2]; + + pair[0] = key; + pair[1] = val; + rb_ary_cat(ary, pair, 2); + + return ST_CONTINUE; +} + /* * call-seq: * hash.flatten -> an_array @@ -2206,15 +2218,17 @@ rb_hash_rassoc(VALUE hash, VALUE obj) static VALUE rb_hash_flatten(int argc, VALUE *argv, VALUE hash) { - VALUE ary, tmp; + VALUE ary; - ary = rb_hash_to_a(hash); - if (argc == 0) { - argc = 1; - tmp = INT2FIX(1); - argv = &tmp; + ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2); + rb_hash_foreach(hash, flatten_i, ary); + if (argc) { + int level = FIX2INT(*argv) - 1; + if (level > 0) { + *argv = INT2FIX(level); + rb_funcall2(ary, rb_intern("flatten!"), argc, argv); + } } - rb_funcall2(ary, rb_intern("flatten!"), argc, argv); return ary; }