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

ruby-changes:46849

From: watson1978 <ko1@a...>
Date: Tue, 30 May 2017 11:57:40 +0900 (JST)
Subject: [ruby-changes:46849] watson1978:r58964 (trunk): Improve performance of Range#{min, max}

watson1978	2017-05-30 11:57:33 +0900 (Tue, 30 May 2017)

  New Revision: 58964

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=58964

  Log:
    Improve performance of Range#{min,max}
    
    range.c (range_min): use OPTIMIZED_CMP() to compare the objects instead of
        `<=>' method dispatching for Fixnum/Float/String object inside Range object.
    
    range.c (range_max): ditto.
    
        Range#min -> 34 % up
        Range#max -> 44 % up
    
        [ruby-core:80713] [Bug #13443] [Fix GH-1585]
    
    ### Before
               Range#min      8.428M (?\194?\177 1.3%) i/s -     42.141M in   5.000952s
               Range#max      8.157M (?\194?\177 1.3%) i/s -     40.852M in   5.009297s
    
    ### After
               Range#min     11.269M (?\194?\177 1.2%) i/s -     56.388M in   5.004611s
               Range#max     11.764M (?\194?\177 1.3%) i/s -     58.856M in   5.003820s
    
    ### Test code
    require 'benchmark/ips'
    
    Benchmark.ips do |x|
      x.report "Range#min" do |i|
        i.times { (1..100).min }
      end
    
      x.report "Range#max" do |i|
        i.times { (1..100).max }
      end
    end

  Modified files:
    trunk/range.c
Index: range.c
===================================================================
--- range.c	(revision 58963)
+++ range.c	(revision 58964)
@@ -914,9 +914,10 @@ range_min(int argc, VALUE *argv, VALUE r https://github.com/ruby/ruby/blob/trunk/range.c#L914
 	return range_first(argc, argv, range);
     }
     else {
+	struct cmp_opt_data cmp_opt = { 0, 0 };
 	VALUE b = RANGE_BEG(range);
 	VALUE e = RANGE_END(range);
-	int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);
+	int c = OPTIMIZED_CMP(b, e, cmp_opt);
 
 	if (c > 0 || (c == 0 && EXCL(range)))
 	    return Qnil;
@@ -951,8 +952,9 @@ range_max(int argc, VALUE *argv, VALUE r https://github.com/ruby/ruby/blob/trunk/range.c#L952
 	return rb_call_super(argc, argv);
     }
     else {
+	struct cmp_opt_data cmp_opt = { 0, 0 };
 	VALUE b = RANGE_BEG(range);
-	int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);
+	int c = OPTIMIZED_CMP(b, e, cmp_opt);
 
 	if (c > 0)
 	    return Qnil;

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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