Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

should not raise an exception, so implement vm_fast_mod(). fix #1471

The modulo between the Fixnum/Float is improved the performance by this patch.

* before
      user     system      total        real
  1.000000   0.000000   1.000000 (  1.000743)
  1.030000   0.000000   1.030000 (  1.030479)
  1.090000   0.000000   1.090000 (  1.097021)

* after
      user     system      total        real
  0.570000   0.000000   0.570000 (  0.577238)
  1.040000   0.000000   1.040000 (  1.031634)
  0.540000   0.000000   0.540000 (  0.539968)

Test Script:
----
require 'benchmark'

Benchmark.bm do |x|
  x.report do
    10_000_000.times do
      42 % 1
    end
  end

  x.report do
    10_000_000.times do
      42 % 1.0
    end
  end

  x.report do
    10_000_000.times do
      42.0 % 1.0
    end
  end
end
  • Loading branch information...
commit a3b91c64b6fa2635f3ce51610f3f4ca9c120a8ec 1 parent 9dec8ce
@Watson1978 Watson1978 authored
Showing with 65 additions and 1 deletion.
  1. +5 −1 compiler.cpp
  2. +1 −0  compiler.h
  3. +1 −0  exported_symbols_list
  4. +58 −0 kernel.c
View
6 compiler.cpp
@@ -172,6 +172,7 @@ RoxorCompiler::RoxorCompiler(bool _debug_mode)
fastMinusFunc = get_function("vm_fast_minus");
fastMultFunc = get_function("vm_fast_mult");
fastDivFunc = get_function("vm_fast_div");
+ fastModFunc = get_function("vm_fast_mod");
fastLtFunc = get_function("vm_fast_lt");
fastLeFunc = get_function("vm_fast_le");
fastGtFunc = get_function("vm_fast_gt");
@@ -2298,7 +2299,7 @@ RoxorCompiler::compile_optimized_dispatch_call(SEL sel, int argc,
return pn;
}
// Pure arithmetic operations.
- else if (sel == selPLUS || sel == selMINUS || sel == selDIV
+ else if (sel == selPLUS || sel == selMINUS || sel == selDIV || sel == selMOD
|| sel == selMULT || sel == selLT || sel == selLE
|| sel == selGT || sel == selGE || sel == selEq
|| sel == selNeq || sel == selEqq) {
@@ -2320,6 +2321,9 @@ RoxorCompiler::compile_optimized_dispatch_call(SEL sel, int argc,
else if (sel == selDIV) {
func = fastDivFunc;
}
+ else if (sel == selMOD) {
+ func = fastModFunc;
+ }
else if (sel == selMULT) {
func = fastMultFunc;
}
View
1  compiler.h
@@ -159,6 +159,7 @@ class RoxorCompiler {
Function *fastMinusFunc;
Function *fastMultFunc;
Function *fastDivFunc;
+ Function *fastModFunc;
Function *fastLtFunc;
Function *fastLeFunc;
Function *fastGtFunc;
View
1  exported_symbols_list
@@ -14,6 +14,7 @@ _rstr_concat
_selPLUS
_selMINUS
_selDIV
+_selMOD
_selMULT
_selLT
_selLE
View
58 kernel.c
@@ -439,6 +439,64 @@ vm_fast_div(VALUE left, VALUE right, unsigned char overriden)
}
PRIMITIVE VALUE
+vm_fast_mod(VALUE left, VALUE right, unsigned char overriden)
+{
+ if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
+ if (FIXNUM_P(left) && FIXNUM_P(right)) {
+ const long x = FIX2LONG(left);
+ const long y = FIX2LONG(right);
+ long div, mod;
+
+ if (y == 0) {
+ rb_num_zerodiv();
+ }
+ if (y < 0) {
+ if (x < 0) {
+ div = -x / -y;
+ }
+ else {
+ div = - (x / -y);
+ }
+ }
+ else {
+ if (x < 0) {
+ div = - (-x / y);
+ }
+ else {
+ div = x / y;
+ }
+ }
+ mod = x - div*y;
+ if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
+ mod += y;
+ div -= 1;
+ }
+ return LONG2FIX(mod);
+ }
+ else if (FIXFLOAT_P(left) && FIXFLOAT_P(right)) {
+ const double x = IMM2DBL(left);
+ const double y = IMM2DBL(right);
+ double div, mod;
+
+#ifdef HAVE_FMOD
+ mod = fmod(x, y);
+#else
+ double z;
+ modf(x/y, &z);
+ mod = x - z * y;
+#endif
+ div = (x - mod) / y;
+ if (y * mod < 0) {
+ mod += y;
+ div -= 1.0;
+ }
+ return DBL2FIXFLOAT(mod);
+ }
+ }
+ return vm_dispatch(0, left, selMOD, NULL, 0, 1, &right);
+}
+
+PRIMITIVE VALUE
vm_fast_lt(VALUE left, VALUE right, unsigned char overriden)
{
if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {

0 comments on commit a3b91c6

Please sign in to comment.
Something went wrong with that request. Please try again.