Optimize each_sum for hashes
* enum.c (enum_sum, hash_sum, hash_sum_i, enum_sum_i, sum_iter): Optimize for hashes when each method isn't redefined. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55041 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
eb9c9964b0
commit
49432957c7
@ -1,3 +1,8 @@
|
|||||||
|
Wed May 18 09:52:00 2016 Kenta Murata <mrkn@mrkn.jp>
|
||||||
|
|
||||||
|
* enum.c (enum_sum, hash_sum, hash_sum_i, enum_sum_i, sum_iter):
|
||||||
|
Optimize for hashes when each method isn't redefined.
|
||||||
|
|
||||||
Wed May 18 09:14:00 2016 Kenta Murata <mrkn@mrkn.jp>
|
Wed May 18 09:14:00 2016 Kenta Murata <mrkn@mrkn.jp>
|
||||||
|
|
||||||
* enum.c (enum_sum, int_range_sum): Extract int_range_sum from
|
* enum.c (enum_sum, int_range_sum): Extract int_range_sum from
|
||||||
|
39
enum.c
39
enum.c
@ -13,6 +13,8 @@
|
|||||||
#include "ruby/util.h"
|
#include "ruby/util.h"
|
||||||
#include "id.h"
|
#include "id.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
VALUE rb_mEnumerable;
|
VALUE rb_mEnumerable;
|
||||||
|
|
||||||
static ID id_next;
|
static ID id_next;
|
||||||
@ -3569,18 +3571,17 @@ struct enum_sum_memo {
|
|||||||
int float_value;
|
int float_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
static VALUE
|
static void
|
||||||
enum_sum_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
|
sum_iter(VALUE i, struct enum_sum_memo *memo)
|
||||||
{
|
{
|
||||||
struct enum_sum_memo *memo = (struct enum_sum_memo *)args;
|
assert(memo != NULL);
|
||||||
|
|
||||||
long n = memo->n;
|
long n = memo->n;
|
||||||
VALUE v = memo->v;
|
VALUE v = memo->v;
|
||||||
VALUE r = memo->r;
|
VALUE r = memo->r;
|
||||||
double f = memo->f;
|
double f = memo->f;
|
||||||
double c = memo->c;
|
double c = memo->c;
|
||||||
|
|
||||||
ENUM_WANT_SVALUE();
|
|
||||||
|
|
||||||
if (memo->block_given)
|
if (memo->block_given)
|
||||||
i = rb_yield(i);
|
i = rb_yield(i);
|
||||||
|
|
||||||
@ -3662,10 +3663,32 @@ enum_sum_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
|
|||||||
memo->r = r;
|
memo->r = r;
|
||||||
memo->f = f;
|
memo->f = f;
|
||||||
memo->c = c;
|
memo->c = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
enum_sum_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
|
||||||
|
{
|
||||||
|
ENUM_WANT_SVALUE();
|
||||||
|
sum_iter(i, (struct enum_sum_memo *) args);
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
hash_sum_i(VALUE key, VALUE value, VALUE arg)
|
||||||
|
{
|
||||||
|
sum_iter(rb_assoc_new(key, value), (struct enum_sum_memo *) arg);
|
||||||
|
return ST_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
hash_sum(VALUE hash, struct enum_sum_memo *memo)
|
||||||
|
{
|
||||||
|
assert(RB_TYPE_P(hash, T_HASH));
|
||||||
|
assert(memo != NULL);
|
||||||
|
|
||||||
|
rb_hash_foreach(hash, hash_sum_i, (VALUE)memo);
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
int_range_sum(VALUE beg, VALUE end, int excl, VALUE init)
|
int_range_sum(VALUE beg, VALUE end, int excl, VALUE init)
|
||||||
{
|
{
|
||||||
@ -3743,7 +3766,11 @@ enum_sum(int argc, VALUE* argv, VALUE obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_block_call(obj, id_each, 0, 0, enum_sum_iter_i, (VALUE)&memo);
|
if (RB_TYPE_P(obj, T_HASH) &&
|
||||||
|
rb_method_basic_definition_p(CLASS_OF(obj), id_each))
|
||||||
|
hash_sum(obj, &memo);
|
||||||
|
else
|
||||||
|
rb_block_call(obj, id_each, 0, 0, enum_sum_i, (VALUE)&memo);
|
||||||
|
|
||||||
if (memo.float_value) {
|
if (memo.float_value) {
|
||||||
return DBL2NUM(memo.f);
|
return DBL2NUM(memo.f);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user