Improve peformance of Long.hashCode

This commit is contained in:
Alexey Andreev 2017-05-07 22:18:10 +03:00
parent 48d14570b2
commit 2d5f6a81c2
3 changed files with 42 additions and 3 deletions

View File

@ -198,7 +198,7 @@ public class TLong extends TNumber implements TComparable<TLong> {
} }
private static int hashCode(long value) { private static int hashCode(long value) {
return (int) (value ^ (value >>> 32)); return (int) value ^ (int) (value >>> 32);
} }
@Override @Override

View File

@ -881,8 +881,14 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
switch (expr.getTarget()) { switch (expr.getTarget()) {
case INT: case INT:
precedence = Precedence.MEMBER_ACCESS; precedence = Precedence.MEMBER_ACCESS;
Expr longShifted = extractLongRightShiftedBy32(expr.getValue());
if (longShifted != null) {
longShifted.acceptVisitor(this);
writer.append(".hi");
} else {
expr.getValue().acceptVisitor(this); expr.getValue().acceptVisitor(this);
writer.append(".lo"); writer.append(".lo");
}
break; break;
case FLOAT: case FLOAT:
case DOUBLE: case DOUBLE:
@ -927,6 +933,31 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
} }
} }
private Expr extractLongRightShiftedBy32(Expr expr) {
if (!(expr instanceof BinaryExpr)) {
return null;
}
BinaryExpr binary = (BinaryExpr) expr;
if (binary.getOperation() != BinaryOperation.RIGHT_SHIFT
&& binary.getOperation() != BinaryOperation.UNSIGNED_RIGHT_SHIFT) {
return null;
}
if (binary.getType() != OperationType.LONG) {
return null;
}
if (!(binary.getSecondOperand() instanceof ConstantExpr)) {
return null;
}
Object rightConstant = ((ConstantExpr) binary.getSecondOperand()).getValue();
if (rightConstant.equals(32) || rightConstant.equals(32L)) {
return binary.getFirstOperand();
}
return null;
}
@Override @Override
public void visit(ConditionalExpr expr) { public void visit(ConditionalExpr expr) {
try { try {

View File

@ -15,9 +15,11 @@
*/ */
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.teavm.junit.SkipJVM;
import org.teavm.junit.TeaVMTestRunner; import org.teavm.junit.TeaVMTestRunner;
@RunWith(TeaVMTestRunner.class) @RunWith(TeaVMTestRunner.class)
@ -30,4 +32,10 @@ public class LongTest {
assertTrue(Long.compare(Long.MAX_VALUE, Long.MIN_VALUE) > 0); assertTrue(Long.compare(Long.MAX_VALUE, Long.MIN_VALUE) > 0);
assertTrue(Long.compare(Long.MIN_VALUE, Long.MAX_VALUE) < 0); assertTrue(Long.compare(Long.MIN_VALUE, Long.MAX_VALUE) < 0);
} }
@Test
@SkipJVM
public void calculatesHashCode() {
assertEquals(23 ^ 42, Long.hashCode((23L << 32) | 42));
}
} }