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

ruby-changes:65593

From: Nobuyoshi <ko1@a...>
Date: Wed, 17 Mar 2021 00:01:08 +0900 (JST)
Subject: [ruby-changes:65593] 382d3a4516 (master): Improve Enumerable#tally performance

https://git.ruby-lang.org/ruby.git/commit/?id=382d3a4516

From 382d3a4516a8177acbd23e8f87e766e38cce36a8 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Tue, 16 Mar 2021 22:14:56 +0900
Subject: Improve Enumerable#tally performance

Iteration per second (i/s)

|       |compare-ruby|built-ruby|
|:------|-----------:|---------:|
|tally  |      52.814|   114.936|
|       |           -|     2.18x|
---
 benchmark/enum_tally.yml |  4 ++++
 enum.c                   | 20 ++++++++++++++------
 2 files changed, 18 insertions(+), 6 deletions(-)
 create mode 100644 benchmark/enum_tally.yml

diff --git a/benchmark/enum_tally.yml b/benchmark/enum_tally.yml
new file mode 100644
index 0000000..edd2e04
--- /dev/null
+++ b/benchmark/enum_tally.yml
@@ -0,0 +1,4 @@ https://github.com/ruby/ruby/blob/trunk/benchmark/enum_tally.yml#L1
+prelude: |
+  list = ("aaa".."zzz").to_a*10
+benchmark:
+  tally: list.tally
diff --git a/enum.c b/enum.c
index ef35f9b..d8eefc8 100644
--- a/enum.c
+++ b/enum.c
@@ -1008,11 +1008,11 @@ enum_group_by(VALUE obj) https://github.com/ruby/ruby/blob/trunk/enum.c#L1008
     return enum_hashify(obj, 0, 0, group_by_i);
 }
 
-static void
-tally_up(VALUE hash, VALUE group)
+static int
+tally_up(st_data_t *group, st_data_t *value, st_data_t arg, int existing)
 {
-    VALUE tally = rb_hash_aref(hash, group);
-    if (NIL_P(tally)) {
+    VALUE tally = (VALUE)*value;
+    if (!existing) {
         tally = INT2FIX(1);
     }
     else if (FIXNUM_P(tally) && tally < INT2FIX(FIXNUM_MAX)) {
@@ -1021,14 +1021,22 @@ tally_up(VALUE hash, VALUE group) https://github.com/ruby/ruby/blob/trunk/enum.c#L1021
     else {
         tally = rb_big_plus(tally, INT2FIX(1));
     }
-    rb_hash_aset(hash, group, tally);
+    *value = (st_data_t)tally;
+    return ST_CONTINUE;
+}
+
+static VALUE
+rb_enum_tally_up(VALUE hash, VALUE group)
+{
+    rb_hash_stlike_update(hash, group, tally_up, 0);
+    return hash;
 }
 
 static VALUE
 tally_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
 {
     ENUM_WANT_SVALUE();
-    tally_up(hash, i);
+    rb_enum_tally_up(hash, i);
     return Qnil;
 }
 
-- 
cgit v1.1


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

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