[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]