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/