From c3bbc818af54ecf70933c04aad10c3e0d140926f Mon Sep 17 00:00:00 2001 From: mrkn Date: Thu, 13 Apr 2017 07:22:35 +0000 Subject: array.c: Improve performance of Array#sort with float elements * array.c (sort_2): improve performance of Array#sort with float elements. * internal.h (cmp_opt_Float, cmp_opt_data): added for checking whether or not Float#<=> can be optimizable. * numeric.c (rb_float_cmp): added for internal use. * internal.h (rb_float_cmp): ditto. [Bug #13340] [ruby-dev:50023] [Fix GH-1539] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58333 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- array.c | 3 +++ internal.h | 4 ++++ numeric.c | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/array.c b/array.c index 329061f9c0..e07e91bc3c 100644 --- a/array.c +++ b/array.c @@ -2420,6 +2420,9 @@ sort_2(const void *ap, const void *bp, void *dummy) if (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(data->cmp_opt, String)) { return rb_str_cmp(a, b); } + if (RB_FLOAT_TYPE_P(a) && CMP_OPTIMIZABLE(data->cmp_opt, Float)) { + return rb_float_cmp(a, b); + } retval = rb_funcallv(a, id_cmp, 1, &b); n = rb_cmpint(retval, a, b); diff --git a/internal.h b/internal.h index c87d087d0d..7bc64223af 100644 --- a/internal.h +++ b/internal.h @@ -958,6 +958,7 @@ struct MEMO { enum { cmp_opt_Fixnum, cmp_opt_String, + cmp_opt_Float, cmp_optimizable_count }; @@ -981,6 +982,8 @@ struct cmp_opt_data { (((long)a > (long)b) ? 1 : ((long)a < (long)b) ? -1 : 0) : \ (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(data, String)) ? \ rb_str_cmp(a, b) : \ + (RB_FLOAT_TYPE_P(a) && RB_FLOAT_TYPE_P(b) && CMP_OPTIMIZABLE(data, Float)) ? \ + rb_float_cmp(a, b) : \ rb_cmpint(rb_funcallv(a, id_cmp, 1, &b), a, b)) /* ment is in method.h */ @@ -1318,6 +1321,7 @@ VALUE rb_int2str(VALUE num, int base); VALUE rb_dbl_hash(double d); VALUE rb_fix_plus(VALUE x, VALUE y); VALUE rb_int_gt(VALUE x, VALUE y); +int rb_float_cmp(VALUE x, VALUE y); VALUE rb_float_gt(VALUE x, VALUE y); VALUE rb_int_ge(VALUE x, VALUE y); enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts); diff --git a/numeric.c b/numeric.c index f8f0766940..f66fdaef54 100644 --- a/numeric.c +++ b/numeric.c @@ -1520,6 +1520,12 @@ flo_cmp(VALUE x, VALUE y) return rb_dbl_cmp(a, b); } +int +rb_float_cmp(VALUE x, VALUE y) +{ + return NUM2INT(flo_cmp(x, y)); +} + /* * call-seq: * float > real -> true or false -- cgit v1.2.3