Frequent access to mod32 operation defined on the Number.prototype is slowing things down significanty. FasterSieve
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 24 Jan 2016 14:31:36 +0100
branchFasterSieve
changeset 195071e5cd5b29bc
parent 1854 826eb936c9a8
child 1951 3781fd782472
Frequent access to mod32 operation defined on the Number.prototype is slowing things down significanty.
benchmarks/sieve/src/test/java/org/apidesign/benchmark/sieve/SieveTest.java
rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js
rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java
     1.1 --- a/benchmarks/sieve/src/test/java/org/apidesign/benchmark/sieve/SieveTest.java	Sun Jan 24 12:08:45 2016 +0100
     1.2 +++ b/benchmarks/sieve/src/test/java/org/apidesign/benchmark/sieve/SieveTest.java	Sun Jan 24 14:31:36 2016 +0100
     1.3 @@ -40,7 +40,7 @@
     1.4      public int oneThousand() throws IOException {
     1.5          SieveTest sieve = new SieveTest();
     1.6          int now = time();
     1.7 -        int res = sieve.compute(1000);
     1.8 +        int res = sieve.compute(5000);
     1.9          int took = time() - now;
    1.10          log("oneThousand in " + took + " ms");
    1.11          return res;
    1.12 @@ -54,5 +54,6 @@
    1.13      @JavaScriptBody(args = { "msg" }, body = "if (typeof console !== 'undefined') console.log(msg);")
    1.14      @Override
    1.15      protected void log(String msg) {
    1.16 +        System.err.println(msg);
    1.17      }
    1.18  }
     2.1 --- a/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js	Sun Jan 24 12:08:45 2016 +0100
     2.2 +++ b/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js	Sun Jan 24 14:31:36 2016 +0100
     2.3 @@ -1,5 +1,4 @@
     2.4  // empty line needed here
     2.5 -
     2.6  (function(numberPrototype) {
     2.7      numberPrototype.add32 = function(x) {
     2.8          return (this + x) | 0;
     2.9 @@ -498,12 +497,11 @@
    2.10          return (this / x) | 0;
    2.11      }
    2.12  
    2.13 -    numberPrototype.mod32 = function(x) {
    2.14 +    myNum.mod32 = function(a, x) {
    2.15          if (x === 0) {
    2.16              __handleDivByZero();
    2.17          }
    2.18 -
    2.19 -        return (this % x);
    2.20 +        return a % x;
    2.21      }
    2.22  
    2.23      numberPrototype.div64 = function(x) {
     3.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sun Jan 24 12:08:45 2016 +0100
     3.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sun Jan 24 14:31:36 2016 +0100
     3.3 @@ -775,8 +775,15 @@
     3.4                      smapper.replace(this, VarType.DOUBLE, "(@1 / @2)", smapper.getD(1), smapper.popD());
     3.5                      break;
     3.6                  case opc_irem:
     3.7 -                    smapper.replace(this, VarType.INTEGER, "(@1).mod32(@2)",
     3.8 +//
     3.9 +// direct check yields few percents
    3.10 +// in case of firefox 5.8s/4.6.s
    3.11 +                    smapper.replace(this, VarType.INTEGER, "((@1) % (@2))",
    3.12                           smapper.getI(1), smapper.popI());
    3.13 +// with myNum being local variable in the generated script
    3.14 +// it compiles and computes 5000 primes in 6s
    3.15 +//                    smapper.replace(this, VarType.INTEGER, "myNum.mod32(@1, @2)",
    3.16 +//                         smapper.getI(1), smapper.popI());
    3.17                      break;
    3.18                  case opc_lrem:
    3.19                      smapper.replace(this, VarType.LONG, "(@1).mod64(@2)",
     4.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Sun Jan 24 12:08:45 2016 +0100
     4.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Sun Jan 24 14:31:36 2016 +0100
     4.3 @@ -459,7 +459,15 @@
     4.4  
     4.5          @Override
     4.6          protected void generatePrologue() throws IOException {
     4.7 -            append("(function VM(global) {var fillInVMSkeleton = function(vm) {");
     4.8 +            append("(function VM(global) {var myNum = {};\n"
     4.9 +                + "    myNum.mod32 = function(a, x) {\n"
    4.10 +                + "        if (x === 0) {\n"
    4.11 +                + "            __handleDivByZero();\n"
    4.12 +                + "        }\n"
    4.13 +                + "        return a % x;\n"
    4.14 +                + "    }\n"
    4.15 +                + ""
    4.16 +                + "var fillInVMSkeleton = function(vm) {");
    4.17          }
    4.18  
    4.19          @Override
    4.20 @@ -731,6 +739,14 @@
    4.21              }
    4.22              append(
    4.23                    "\n}, function(exports) {\n"
    4.24 +                + "  var myNum = {};\n"
    4.25 +                      + "    myNum.mod32 = function(a, x) {\n"
    4.26 +                + "        if (x === 0) {\n"
    4.27 +                + "            __handleDivByZero();\n"
    4.28 +                + "        }\n"
    4.29 +                + "        return a % x;\n"
    4.30 +                + "    }\n"
    4.31 +                + ""
    4.32                  + "  var vm = {};\n");
    4.33              append("  function link(n, assign) {\n"
    4.34                  + "    return function() {\n"