summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authorglass <glass@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-18 08:48:12 +0000
committerglass <glass@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-18 08:48:12 +0000
commit852caed8a375ba761a786fc6c3d0da644422434f (patch)
tree62a0e921f909a1ccd63218f2920cb8b19ea2c249 /hash.c
parentfaa9d5eced17729f0a6edda4ba445dec26ca73a5 (diff)
* 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
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c28
1 files changed, 21 insertions, 7 deletions
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;
}