Speed-up MULTIANEWARRAY. Temporarily disable typed arrays as they make

benchmark to pass slower
This commit is contained in:
konsoletyper 2014-02-11 12:28:37 +04:00
parent 9929082d49
commit 99333f2370
3 changed files with 140 additions and 29 deletions

View File

@ -18,10 +18,7 @@ package org.teavm.javascript;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.teavm.codegen.NamingException; import org.teavm.codegen.NamingException;
import org.teavm.codegen.NamingStrategy; import org.teavm.codegen.NamingStrategy;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
@ -1084,7 +1081,7 @@ public class Renderer implements ExprVisitor, StatementVisitor {
break; break;
} }
} else { } else {
writer.append("$rt_createArray(").append(typeToClsString(naming, expr.getType())).append(", "); writer.append("$rt_createArray(").append(typeToClsString(naming, expr.getType())).append(",").ws();
expr.getLength().acceptVisitor(this); expr.getLength().acceptVisitor(this);
writer.append(")"); writer.append(")");
} }
@ -1096,10 +1093,46 @@ public class Renderer implements ExprVisitor, StatementVisitor {
@Override @Override
public void visit(NewMultiArrayExpr expr) { public void visit(NewMultiArrayExpr expr) {
try { try {
writer.append("$rt_createMultiArray(").append(typeToClsString(naming, expr.getType())).append(",") ValueType type = expr.getType();
.ws().append("["); for (int i = 0; i < expr.getDimensions().size(); ++i) {
type = ((ValueType.Array)type).getItemType();
}
if (type instanceof ValueType.Primitive) {
switch (((ValueType.Primitive)type).getKind()) {
case BOOLEAN:
writer.append("$rt_createBooleanMultiArray(");
break;
case BYTE:
writer.append("$rt_createByteMultiArray(");
break;
case SHORT:
writer.append("$rt_createShortMultiArray(");
break;
case INTEGER:
writer.append("$rt_createIntMultiArray(");
break;
case LONG:
writer.append("$rt_createLongMultiArray(");
break;
case FLOAT:
writer.append("$rt_createFloatMultiArray(");
break;
case DOUBLE:
writer.append("$rt_createDoubleMultiArray(");
break;
case CHARACTER:
writer.append("$rt_createCharMultiArray(");
break;
}
} else {
writer.append("$rt_createMultiArray(").append(typeToClsString(naming, expr.getType()))
.append(",").ws();
}
writer.append("[");
boolean first = true; boolean first = true;
for (Expr dimension : expr.getDimensions()) { List<Expr> dimensions = new ArrayList<>(expr.getDimensions());
Collections.reverse(dimensions);
for (Expr dimension : dimensions) {
if (!first) { if (!first) {
writer.append(",").ws(); writer.append(",").ws();
} }

View File

@ -38,22 +38,23 @@ $rt_isAssignable = function(from, to) {
$rt_createArray = function(cls, sz) { $rt_createArray = function(cls, sz) {
var data = new Array(sz); var data = new Array(sz);
var arr = new ($rt_arraycls(cls))(data); var arr = new ($rt_arraycls(cls))(data);
arr.$id = $rt_nextId();
for (var i = 0; i < sz; i = (i + 1) | 0) { for (var i = 0; i < sz; i = (i + 1) | 0) {
data[i] = null; data[i] = null;
} }
return arr; return arr;
} }
$rt_createUnfilledArray = function(cls, sz) {
return new ($rt_arraycls(cls))(new Array(sz));
}
$rt_createLongArray = function(sz) { $rt_createLongArray = function(sz) {
var data = new Array(sz); var data = new Array(sz);
var arr = new ($rt_arraycls($rt_longcls()))(data); var arr = new ($rt_arraycls($rt_longcls()))(data);
arr.$id = $rt_nextId();
for (var i = 0; i < sz; i = (i + 1) | 0) { for (var i = 0; i < sz; i = (i + 1) | 0) {
data[i] = Long.ZERO; data[i] = Long.ZERO;
} }
return arr; return arr;
} }
if (ArrayBuffer) { if (false) {
$rt_createNumericArray = function(cls, nativeArray) { $rt_createNumericArray = function(cls, nativeArray) {
return new ($rt_arraycls(cls))(nativeArray); return new ($rt_arraycls(cls))(nativeArray);
} }
@ -82,7 +83,6 @@ if (ArrayBuffer) {
$rt_createNumericArray = function(cls, sz) { $rt_createNumericArray = function(cls, sz) {
var data = new Array(sz); var data = new Array(sz);
var arr = new ($rt_arraycls(cls))(data); var arr = new ($rt_arraycls(cls))(data);
arr.$id = $rt_nextId();
for (var i = 0; i < sz; i = (i + 1) | 0) { for (var i = 0; i < sz; i = (i + 1) | 0) {
data[i] = 0; data[i] = 0;
} }
@ -100,6 +100,7 @@ $rt_arraycls = function(cls) {
if (cls.$array == undefined) { if (cls.$array == undefined) {
var arraycls = function(data) { var arraycls = function(data) {
this.data = data; this.data = data;
this.$id = $rt_nextId();
}; };
arraycls.prototype = new ($rt_objcls())(); arraycls.prototype = new ($rt_objcls())();
arraycls.prototype.constructor = arraycls; arraycls.prototype.constructor = arraycls;
@ -153,7 +154,7 @@ $rt_shortcls = function() {
} }
$rt_intclsCache = null; $rt_intclsCache = null;
$rt_intcls = function() { $rt_intcls = function() {
if ($rt_intclsCache == null) { if ($rt_intclsCache === null) {
$rt_intclsCache = $rt_createcls(); $rt_intclsCache = $rt_createcls();
$rt_intclsCache.primitive = true; $rt_intclsCache.primitive = true;
$rt_intclsCache.name = "int"; $rt_intclsCache.name = "int";
@ -162,7 +163,7 @@ $rt_intcls = function() {
} }
$rt_longclsCache = null; $rt_longclsCache = null;
$rt_longcls = function() { $rt_longcls = function() {
if ($rt_longclsCache == null) { if ($rt_longclsCache === null) {
$rt_longclsCache = $rt_createcls(); $rt_longclsCache = $rt_createcls();
$rt_longclsCache.primitive = true; $rt_longclsCache.primitive = true;
$rt_longclsCache.name = "long"; $rt_longclsCache.name = "long";
@ -171,7 +172,7 @@ $rt_longcls = function() {
} }
$rt_floatclsCache = null; $rt_floatclsCache = null;
$rt_floatcls = function() { $rt_floatcls = function() {
if ($rt_floatclsCache == null) { if ($rt_floatclsCache === null) {
$rt_floatclsCache = $rt_createcls(); $rt_floatclsCache = $rt_createcls();
$rt_floatclsCache.primitive = true; $rt_floatclsCache.primitive = true;
$rt_floatclsCache.name = "float"; $rt_floatclsCache.name = "float";
@ -180,7 +181,7 @@ $rt_floatcls = function() {
} }
$rt_doubleclsCache = null; $rt_doubleclsCache = null;
$rt_doublecls = function() { $rt_doublecls = function() {
if ($rt_doubleclsCache == null) { if ($rt_doubleclsCache === null) {
$rt_doubleclsCache = $rt_createcls(); $rt_doubleclsCache = $rt_createcls();
$rt_doubleclsCache.primitive = true; $rt_doubleclsCache.primitive = true;
$rt_doubleclsCache.name = "double"; $rt_doubleclsCache.name = "double";
@ -189,7 +190,7 @@ $rt_doublecls = function() {
} }
$rt_voidclsCache = null; $rt_voidclsCache = null;
$rt_voidcls = function() { $rt_voidcls = function() {
if ($rt_voidclsCache == null) { if ($rt_voidclsCache === null) {
$rt_voidclsCache = $rt_createcls(); $rt_voidclsCache = $rt_createcls();
$rt_voidclsCache.primitive = true; $rt_voidclsCache.primitive = true;
$rt_voidclsCache.name = "void"; $rt_voidclsCache.name = "void";
@ -234,18 +235,95 @@ $rt_shortToInt = function(value) {
return value > 0xFFFF ? value | 0xFFFF0000 : value; return value > 0xFFFF ? value | 0xFFFF0000 : value;
} }
$rt_createMultiArray = function(cls, dimensions) { $rt_createMultiArray = function(cls, dimensions) {
return $rt_createMultiArrayImpl(cls, dimensions, 0); var arrays = new Array($rt_primitiveArrayCount(dimensions));
} var firstDim = dimensions[0] | 0;
$rt_createMultiArrayImpl = function(cls, dimensions, offset) { for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
cls = cls.$meta.item; arrays[i] = $rt_createArray(cls, firstDim);
var result = $rt_createArray(cls, dimensions[offset]);
offset = (offset + 1) | 0;
if (offset < dimensions.length) {
for (var i = 0; i < result.data.length; i = (i + 1) | 0) {
result.data[i] = $rt_createMultiArrayImpl(cls, dimensions, offset);
}
} }
return result; return $rt_createMultiArrayImpl(cls, arrays, dimensions);
}
$rt_createByteMultiArray = function(dimensions) {
var arrays = new Array($rt_primitiveArrayCount(dimensions));
var firstDim = dimensions[0] | 0;
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
arrays[i] = $rt_createByteArray(firstDim);
}
return $rt_createMultiArrayImpl($rt_bytecls(), arrays, dimensions);
}
$rt_createBooleanMultiArray = function(dimensions) {
var arrays = new Array($rt_primitiveArrayCount(dimensions));
var firstDim = dimensions[0] | 0;
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
arrays[i] = $rt_createBooleanArray(firstDim);
}
return $rt_createMultiArrayImpl($rt_booleancls(), arrays, dimensions);
}
$rt_createShortMultiArray = function(dimensions) {
var arrays = new Array($rt_primitiveArrayCount(dimensions));
var firstDim = dimensions[0] | 0;
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
arrays[i] = $rt_createShortArray(firstDim);
}
return $rt_createMultiArrayImpl($rt_shortcls(), arrays, dimensions);
}
$rt_createIntMultiArray = function(dimensions) {
var arrays = new Array($rt_primitiveArrayCount(dimensions));
var firstDim = dimensions[0] | 0;
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
arrays[i] = $rt_createIntArray(firstDim);
}
return $rt_createMultiArrayImpl($rt_intcls(), arrays, dimensions);
}
$rt_createLongMultiArray = function(dimensions) {
var arrays = new Array($rt_primitiveArrayCount(dimensions));
var firstDim = dimensions[0] | 0;
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
arrays[i] = $rt_createLongArray(firstDim);
}
return $rt_createMultiArrayImpl($rt_longcls(), arrays, dimensions);
}
$rt_createFloatMultiArray = function(dimensions) {
var arrays = new Array($rt_primitiveArrayCount(dimensions));
var firstDim = dimensions[0] | 0;
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
arrays[i] = $rt_createFloatArray(firstDim);
}
return $rt_createMultiArrayImpl($rt_floatcls(), arrays, dimensions);
}
$rt_createDoubleMultiArray = function(dimensions) {
var arrays = new Array($rt_primitiveArrayCount(dimensions));
var firstDim = dimensions[0] | 0;
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
arrays[i] = $rt_createDoubleArray(firstDim);
}
return $rt_createMultiArrayImpl($rt_doublecls(), arrays, dimensions);
}
$rt_primitiveArrayCount = function(dimensions) {
var val = dimensions[1] | 0;
for (var i = 2 | 0; i < dimensions.length; i = (i + 1) | 0) {
val = (val * (dimensions[i] | 0)) | 0;
}
return val;
}
$rt_createMultiArrayImpl = function(cls, arrays, dimensions) {
var limit = arrays.length;
for (var i = 1 | 0; i < dimensions.length; i = (i + 1) | 0) {
cls = $rt_arraycls(cls);
var dim = dimensions[i];
var index = 0;
var packedIndex = 0;
while (index < limit) {
var arr = $rt_createUnfilledArray(cls, dim);
for (var j = 0; j < dim; j = (j + 1) | 0) {
arr.data[j] = arrays[index];
index = (index + 1) | 0;
}
arrays[packedIndex] = arr;
packedIndex = (packedIndex + 1) | 0;
}
limit = packedIndex;
}
return arrays[0];
} }
$rt_assertNotNaN = function(value) { $rt_assertNotNaN = function(value) {
if (typeof value == 'number' && isNaN(value)) { if (typeof value == 'number' && isNaN(value)) {

View File

@ -23,7 +23,7 @@ import java.io.IOException;
*/ */
public class MatrixMultiplication { public class MatrixMultiplication {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
for (int k = 0; k < 100; ++k) { for (int k = 0; k < 20; ++k) {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
Matrix m1 = new Matrix(5); Matrix m1 = new Matrix(5);