ruby-changes:34783
From: nobu <ko1@a...>
Date: Fri, 18 Jul 2014 22:17:18 +0900 (JST)
Subject: [ruby-changes:34783] nobu:r46866 (trunk): optimized any? methods
nobu 2014-07-18 22:16:48 +0900 (Fri, 18 Jul 2014) New Revision: 46866 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46866 Log: 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?. Modified files: trunk/array.c trunk/hash.c trunk/test/ruby/test_settracefunc.rb Index: array.c =================================================================== --- array.c (revision 46865) +++ array.c (revision 46866) @@ -5409,6 +5409,29 @@ rb_ary_drop_while(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L5409 } /* + * 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. * * Array indexing starts at 0, as in C or Java. A negative index is assumed @@ -5757,6 +5780,7 @@ Init_Array(void) https://github.com/ruby/ruby/blob/trunk/array.c#L5780 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"); Index: hash.c =================================================================== --- hash.c (revision 46865) +++ hash.c (revision 46866) @@ -2463,6 +2463,52 @@ rb_hash_compare_by_id_p(VALUE hash) https://github.com/ruby/ruby/blob/trunk/hash.c#L2463 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) https://github.com/ruby/ruby/blob/trunk/hash.c#L3907 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. Index: test/ruby/test_settracefunc.rb =================================================================== --- test/ruby/test_settracefunc.rb (revision 46865) +++ test/ruby/test_settracefunc.rb (revision 46866) @@ -285,11 +285,9 @@ class TestSetTraceFunc < Test::Unit::Tes https://github.com/ruby/ruby/blob/trunk/test/ruby/test_settracefunc.rb#L285 [["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) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/