Skip to content

Commit

Permalink
Starlark: optimize StarlarkInt.Big comparison to StarlarkInt.Int{32,64}
Browse files Browse the repository at this point in the history
Perform comparison without conversion of smaller integers to
`BigInteger`.  `StarlarkInt.compareTo` does not allocate now.

For this benchmark:

```
def test():
    x = 17 << 77
    for i in range(10):
        print(i)
        for j in range(10000000):
            x > 1

test()
```

```
A: n=27 mean=4.262 std=0.203 se=0.039 min=4.036 med=4.193
B: n=27 mean=4.113 std=0.172 se=0.033 min=3.859 med=4.049
B/A: 0.965 0.941..0.990 (95% conf)
```

Speed up is about 7% when comparing to an integer outside of
`BigInteger` cached range (-16..16).

Finally, `StarlarkInt.Big` to `StarlarkInt.Big` comparison performance
seems to stay the same (within 95% confidence interval after 100
test iterations).
  • Loading branch information
stepancheg committed Dec 5, 2020
1 parent 46468e4 commit 2cedae9
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion src/main/java/net/starlark/java/eval/StarlarkInt.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ public int signum() {
return Integer.signum(v);
}

@Override
protected int orderOfMagnitude() {
return Integer.signum(v);
}

@Override
public void repr(Printer printer) {
printer.append(v);
Expand Down Expand Up @@ -253,6 +258,11 @@ public int signum() {
return Long.signum(v);
}

@Override
protected int orderOfMagnitude() {
return Long.signum(v) * 2;
}

@Override
public void repr(Printer printer) {
printer.append(v);
Expand Down Expand Up @@ -293,6 +303,11 @@ public int signum() {
return v.signum();
}

@Override
protected int orderOfMagnitude() {
return v.signum() * 3;
}

@Override
public void repr(Printer printer) {
printer.append(v.toString());
Expand All @@ -316,6 +331,9 @@ public boolean equals(Object that) {
/** Returns the signum of this StarlarkInt (-1, 0, or +1). */
public abstract int signum();

/** Return 0 for 0, +/-1 for non-zero Int32, +/-2 for Int64, +/-3 for Big. */
protected abstract int orderOfMagnitude();

/** Returns this StarlarkInt as a string of decimal digits. */
@Override
public String toString() {
Expand Down Expand Up @@ -446,7 +464,13 @@ public static int compare(StarlarkInt x, StarlarkInt y) {
/* fall through */
}

return x.toBigInteger().compareTo(y.toBigInteger());
int xo = x.orderOfMagnitude();
int yo = y.orderOfMagnitude();
if (xo != yo) {
return Integer.compare(xo, yo);
}

return ((Big) x).v.compareTo(((Big) y).v);
}

/** Returns x + y. */
Expand Down

0 comments on commit 2cedae9

Please sign in to comment.