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:
parent
e23d173679
commit
d738e3e155
3 changed files with 74 additions and 4 deletions
24
array.c
24
array.c
|
@ -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
48
hash.c
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue