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) {
return (int) (value ^ (value >>> 32));
return (int) value ^ (int) (value >>> 32);
}
@Override

View File

@ -881,8 +881,14 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
switch (expr.getTarget()) {
case INT:
precedence = Precedence.MEMBER_ACCESS;
expr.getValue().acceptVisitor(this);
writer.append(".lo");
Expr longShifted = extractLongRightShiftedBy32(expr.getValue());
if (longShifted != null) {
longShifted.acceptVisitor(this);
writer.append(".hi");
} else {
expr.getValue().acceptVisitor(this);
writer.append(".lo");
}
break;
case FLOAT:
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
public void visit(ConditionalExpr expr) {
try {

View File

@ -15,9 +15,11 @@
*/
package org.teavm.classlib.java.lang;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.teavm.junit.SkipJVM;
import org.teavm.junit.TeaVMTestRunner;
@RunWith(TeaVMTestRunner.class)
@ -30,4 +32,10 @@ public class LongTest {
assertTrue(Long.compare(Long.MAX_VALUE, Long.MIN_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));
}
}