mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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) ```
This commit is contained in:
parent
24e33b84b5
commit
803a072630
Notes:
git
2022-08-12 15:58:13 +09:00
2 changed files with 17 additions and 23 deletions
23
numeric.c
23
numeric.c
|
@ -4269,28 +4269,6 @@ rb_int_idiv(VALUE x, VALUE y)
|
|||
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)
|
|||
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 */
|
||||
|
|
17
numeric.rb
17
numeric.rb
|
@ -227,6 +227,23 @@ class Integer
|
|||
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:
|
||||
|
|
Loading…
Add table
Reference in a new issue