ruby-changes:72916
From: Kouhei <ko1@a...>
Date: Fri, 12 Aug 2022 15:58:02 +0900 (JST)
Subject: [ruby-changes:72916] 803a072630 (master): Improve performance of Integer#ceildiv
https://git.ruby-lang.org/ruby.git/commit/?id=803a072630 From 803a07263001e5466bba0f53fcc85784f4b5c686 Mon Sep 17 00:00:00 2001 From: Kouhei Yanagita <yanagi@s...> Date: Fri, 22 Jul 2022 12:05:16 +0900 Subject: Improve performance of Integer#ceildiv This patch is suggested by nobu. Benchmark result: ``` require 'benchmark' n = 10 ** 7 Benchmark.bm do |x| x.report("Fixnum/Fixnum") { a, b = 5, 2; n.times { a.ceildiv(b) } } x.report("Bignum/Bignum") { a, b = 10**100, 10**99 - 1; n.times { a.ceildiv(b) } } x.report("Bignum/Fixnum") { a, b = 10**100, 3; n.times { a.ceildiv(b) } } end ``` Original: ``` user system total real Fixnum/Fixnum 3.340009 0.043029 3.383038 ( 3.384022) Bignum/Bignum 8.229500 0.118543 8.348043 ( 8.349574) Bignum/Fixnum 8.328971 0.097842 8.426813 ( 8.426952) ``` Improved: ``` user system total real Fixnum/Fixnum 0.699140 0.000961 0.700101 ( 0.700199) Bignum/Bignum 5.076165 0.083160 5.159325 ( 5.159360) Bignum/Fixnum 5.548684 0.115372 5.664056 ( 5.666735) ``` --- numeric.c | 23 ----------------------- numeric.rb | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/numeric.c b/numeric.c index 9574bfe024..4f927f00fb 100644 --- a/numeric.c +++ b/numeric.c @@ -4269,28 +4269,6 @@ rb_int_idiv(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L4269 return num_div(x, y); } -/* - * call-seq: - * ceildiv(other) -> integer - * - * Returns the result of division +self+ by +other+. The result is rounded up to the nearest integer. - * - * 3.ceildiv(3) # => 1 - * 4.ceildiv(3) # => 2 - * - * 4.ceildiv(-3) # => -1 - * -4.ceildiv(3) # => -1 - * -4.ceildiv(-3) # => 2 - * - * 3.ceildiv(1.2) # => 3 - */ -VALUE -rb_int_ceildiv(VALUE x, VALUE y) -{ - VALUE tmp = rb_int_idiv(x, num_uminus(y)); - return num_uminus(tmp); -} - static VALUE fix_mod(VALUE x, VALUE y) { @@ -6277,7 +6255,6 @@ Init_Numeric(void) https://github.com/ruby/ruby/blob/trunk/numeric.c#L6255 rb_define_method(rb_cInteger, "remainder", int_remainder, 1); rb_define_method(rb_cInteger, "divmod", rb_int_divmod, 1); rb_define_method(rb_cInteger, "fdiv", rb_int_fdiv, 1); - rb_define_method(rb_cInteger, "ceildiv", rb_int_ceildiv, 1); rb_define_method(rb_cInteger, "**", rb_int_pow, 1); rb_define_method(rb_cInteger, "pow", rb_int_powm, -1); /* in bignum.c */ diff --git a/numeric.rb b/numeric.rb index 9f2200d2a8..c2091465f8 100644 --- a/numeric.rb +++ b/numeric.rb @@ -227,6 +227,23 @@ class Integer https://github.com/ruby/ruby/blob/trunk/numeric.rb#L227 Primitive.attr! 'inline' Primitive.cexpr! 'rb_int_zero_p(self)' end + + # call-seq: + # ceildiv(other) -> integer + # + # Returns the result of division +self+ by +other+. The result is rounded up to the nearest integer. + # + # 3.ceildiv(3) # => 1 + # 4.ceildiv(3) # => 2 + # + # 4.ceildiv(-3) # => -1 + # -4.ceildiv(3) # => -1 + # -4.ceildiv(-3) # => 2 + # + # 3.ceildiv(1.2) # => 3 + def ceildiv(other) + -div(-other) + end end # call-seq: -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/