1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Improve Enumerable#tally performance

Iteration per second (i/s)

|       |compare-ruby|built-ruby|
|:------|-----------:|---------:|
|tally  |      52.814|   114.936|
|       |           -|     2.18x|
This commit is contained in:
Nobuyoshi Nakada 2021-03-16 22:14:56 +09:00
parent e61e9bcfb2
commit 382d3a4516
No known key found for this signature in database
GPG key ID: 7CD2805BFA3770C6
Notes: git 2021-03-17 00:01:18 +09:00
2 changed files with 18 additions and 6 deletions

4
benchmark/enum_tally.yml Normal file
View file

@ -0,0 +1,4 @@
prelude: |
list = ("aaa".."zzz").to_a*10
benchmark:
tally: list.tally

20
enum.c
View file

@ -1008,11 +1008,11 @@ enum_group_by(VALUE obj)
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)
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;
}