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

optimized any? methods

* array.c (rb_ary_any_p), hash.c (rb_hash_any_p): optimized
  versions.  these are bit faster than optimization in
  Enumerable#any?.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46866 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2014-07-18 13:16:48 +00:00
parent e23d173679
commit d738e3e155
3 changed files with 74 additions and 4 deletions

24
array.c
View file

@ -5408,6 +5408,29 @@ rb_ary_drop_while(VALUE ary)
return rb_ary_drop(ary, LONG2FIX(i));
}
/*
* call-seq:
* ary.any? [{ |obj| block }] -> true or false
*
* See also Enumerable#any?
*/
static VALUE
rb_ary_any_p(VALUE ary)
{
long i, len = RARRAY_LEN(ary);
const VALUE *ptr = RARRAY_CONST_PTR(ary);
if (!len) return Qfalse;
if (!rb_block_given_p()) {
for (i = 0; i < len; ++i) if (RTEST(ptr[i])) return Qtrue;
}
else {
for (i = 0; i < len; ++i) if (RTEST(rb_yield(ptr[i]))) return Qtrue;
}
return Qfalse;
}
/*
* Arrays are ordered, integer-indexed collections of any object.
*
@ -5757,6 +5780,7 @@ Init_Array(void)
rb_define_method(rb_cArray, "drop", rb_ary_drop, 1);
rb_define_method(rb_cArray, "drop_while", rb_ary_drop_while, 0);
rb_define_method(rb_cArray, "bsearch", rb_ary_bsearch, 0);
rb_define_method(rb_cArray, "any?", rb_ary_any_p, 0);
id_cmp = rb_intern("<=>");
id_random = rb_intern("random");

48
hash.c
View file

@ -2463,6 +2463,52 @@ rb_hash_compare_by_id_p(VALUE hash)
return Qfalse;
}
static int
any_p_i(VALUE key, VALUE value, VALUE arg)
{
VALUE ret = rb_yield(rb_assoc_new(key, value));
if (RTEST(ret)) {
*(VALUE *)arg = Qtrue;
return ST_STOP;
}
return ST_CONTINUE;
}
static int
any_p_i_fast(VALUE key, VALUE value, VALUE arg)
{
VALUE ret = rb_yield_values(2, key, value);
if (RTEST(ret)) {
*(VALUE *)arg = Qtrue;
return ST_STOP;
}
return ST_CONTINUE;
}
/*
* call-seq:
* hsh.any? [{ |(key, value)| block }] -> true or false
*
* See also Enumerable#any?
*/
static VALUE
rb_hash_any_p(VALUE hash)
{
VALUE ret = Qfalse;
if (RHASH_EMPTY_P(hash)) return Qfalse;
if (!rb_block_given_p()) {
/* yields pairs, never false */
return Qtrue;
}
if (rb_block_arity() > 1)
rb_hash_foreach(hash, any_p_i_fast, (VALUE)&ret);
else
rb_hash_foreach(hash, any_p_i, (VALUE)&ret);
return ret;
}
static int path_tainted = -1;
static char **origenviron;
@ -3861,6 +3907,8 @@ Init_Hash(void)
rb_define_method(rb_cHash,"compare_by_identity", rb_hash_compare_by_id, 0);
rb_define_method(rb_cHash,"compare_by_identity?", rb_hash_compare_by_id_p, 0);
rb_define_method(rb_cHash, "any?", rb_hash_any_p, 0);
/* Document-class: ENV
*
* ENV is a hash-like accessor for environment variables.

View file

@ -285,11 +285,9 @@ class TestSetTraceFunc < Test::Unit::TestCase
[["c-return", 1, :set_trace_func, Kernel],
["line", 4, __method__, self.class],
["c-call", 4, :any?, Enumerable],
["c-call", 4, :each, Array],
["c-call", 4, :any?, Array],
["line", 4, __method__, self.class],
["c-return", 4, :each, Array],
["c-return", 4, :any?, Enumerable],
["c-return", 4, :any?, Array],
["line", 5, __method__, self.class],
["c-call", 5, :set_trace_func, Kernel]].each{|e|
assert_equal(e, events.shift)