Skip to content

Commit

Permalink
Starlark: use Math.floorDiv in Starlark.floordiv
Browse files Browse the repository at this point in the history
`Math.floorDiv` does multiplication to compute a remainder.

JVM is supposed to
[detect a pair of division and remainder](http://hg.openjdk.java.net/jdk9/jdk9/hotspot/file/jdk-9+181/src/share/vm/opto/compile.cpp#l3176)
when C2 is kicked in, but somehow it seems to not do it on my laptop.

Benchmark can be made a little even more faster by
[adding `yl - 1` instead of multiplication](https://git.io/JIYY6)
but better keep implementation simple.

Anyway, using `Math.floorDiv` is a safe bet.

```
def test():
    for i in range(10):
        print(i)
        for j in range(1000000):
            1 // 100
            1000 // 20
            -1 // 30
            -33 // 9
            500000 / 22
            1 // 100
            1000 // 20
            1 // 30
            3306 // 11
            500000 // 22

test()
```

```
A: n=80 mean=5.149 std=0.317 se=0.035 min=4.709 med=5.102
B: n=80 mean=4.634 std=0.280 se=0.031 min=4.234 med=4.552
B/A: 0.900 0.883..0.918 (95% conf)
```

Closes #12621.

PiperOrigin-RevId: 345857371
  • Loading branch information
stepancheg authored and copybara-github committed Dec 5, 2020
1 parent 9b9bda6 commit 46468e4
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 5 deletions.
6 changes: 1 addition & 5 deletions src/main/java/net/starlark/java/eval/StarlarkInt.java
Original file line number Diff line number Diff line change
Expand Up @@ -526,11 +526,7 @@ public static StarlarkInt floordiv(StarlarkInt x, StarlarkInt y) throws EvalExce
long xl = ((Int32) x).v;
long yl = ((Int32) y).v;
// http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html
long quo = xl / yl;
long rem = xl % yl;
if ((xl < 0) != (yl < 0) && rem != 0) {
quo--;
}
long quo = Math.floorDiv(xl, yl);
return StarlarkInt.of(quo);
}

Expand Down
6 changes: 6 additions & 0 deletions src/test/java/net/starlark/java/eval/testdata/int.star
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ assert_eq(98 // 7, 14)
assert_eq(98 // -7, -14)
assert_eq(-98 // 7, -14)
assert_eq(-98 // -7, 14)
assert_eq(1 // 7, 0)
assert_eq(1 // -7, -1)
assert_eq(-1 // 7, -1)
assert_eq(-1 // -7, 0)
assert_eq(0 // 3, 0)
assert_eq(0 // -3, 0)
assert_eq( product // 1234567, 1169282890553)
assert_eq( product // -1234567, -1169282890553-1)
assert_eq(-product // 1234567, -1169282890553-1)
Expand Down

0 comments on commit 46468e4

Please sign in to comment.