-
-
Save Smerity/5377142 to your computer and use it in GitHub Desktop.
| GCCGo / Go slow "big" package discussion from some time ago | |
| Back at that point, Go's 6g compiler had an implementation of the big package with assembler implementations that hadn't been ported to GCCGo. | |
| https://groups.google.com/forum/?fromgroups=#!searchin/golang-nuts/Is$20Go$20%22big%22$20package$20slow?$20is$20Go$20slow?/golang-nuts/ChpHRdGU8ks/gyhBjheZmSEJ | |
| Neither Java, PyPy, CPython, Go or GCCGo use GMP | |
| CPython and PyPy can "cheat" on small integers as they use normal ints until big integers are required. | |
| To make the comparison only over bigints, I've ensured all integers are > 64 bits. | |
| smerity@pegasus:~/Coding/goxercise$ time go run factors.go | |
| 496968652506233122158689 | |
| real 0m3.503s | |
| user 0m3.516s | |
| sys 0m0.056s | |
| smerity@pegasus:~/Coding/goxercise$ gccgo -O3 factors.go && time ./a.out | |
| 496968652506233122158689 | |
| real 0m8.453s | |
| user 0m8.421s | |
| sys 0m0.004s | |
| smerity@pegasus:~/Coding/goxercise$ time python factors.py | |
| 496968652506233122158689 | |
| real 0m1.899s | |
| user 0m1.880s | |
| sys 0m0.012s | |
| smerity@pegasus:~/Coding/goxercise$ time ~/Coding/Reference/pypy-2.0-beta1/bin/pypy factors.py | |
| 496968652506233122158689 | |
| real 0m1.169s | |
| user 0m1.148s | |
| sys 0m0.016s | |
| smerity@pegasus:~/Coding/goxercise$ time java Factors | |
| 496968652506233122158689 | |
| real 0m1.614s | |
| user 0m1.656s | |
| sys 0m0.092s |
| package main | |
| import ( | |
| "fmt" | |
| "math/big" | |
| ) | |
| func main() { | |
| // 157 bit n = pq with p ~= 78 bits | |
| n := big.NewInt(0) | |
| n.SetString("273966616513101251352941655302036077733021013991", 10) | |
| i := big.NewInt(0) | |
| // Set i to be p - 10e6 | |
| i.SetString("496968652506233112158689", 10) | |
| // Move temp big int out here so no possible GC thrashing | |
| temp := big.NewInt(0) | |
| // Avoid creating the new bigint each time | |
| two := big.NewInt(2) | |
| for { | |
| // Check if the odd number is a divisor of n | |
| temp.Mod(n, i) | |
| if temp.Sign() == 0 { | |
| fmt.Println(i) | |
| break | |
| } | |
| i.Add(i, two) | |
| } | |
| } |
| import java.math.BigInteger; | |
| class Factors { | |
| public static void main (String [] args) | |
| { | |
| // 157 bit n = pq with p ~= 78 bits | |
| BigInteger n = new BigInteger("273966616513101251352941655302036077733021013991"); | |
| // Set i to be p - 10e6 | |
| BigInteger i = new BigInteger("496968652506233112158689"); | |
| // Avoid creating a new bigint each time | |
| BigInteger two = new BigInteger("2"); | |
| while (true) { | |
| if (n.mod(i).equals(BigInteger.ZERO)) { | |
| System.out.println(i); | |
| break; | |
| } | |
| i = i.add(two); | |
| } | |
| } | |
| } |
| # 157 bit n = pq with p ~= 78 bits | |
| n = 273966616513101251352941655302036077733021013991 | |
| i = 496968652506233112158689 # prime minus 10e6 | |
| while True: | |
| if n % i == 0: | |
| print i | |
| break | |
| i += 2 |
Compiling in go is very fast.
$ time go run factors.go
496968652506233122158689
real 0m4.917s
user 0m4.461s
sys 0m0.532s
$ go build factors.go
$ time ./factors
496968652506233122158689
real 0m4.178s
user 0m4.193s
sys 0m0.300s
I just re-did the test and added a Makefile to make it easy to redo the check: https://gist.github.com/ArneBab/eea6d1943c51dbddffe0fedd01b9a881
Typical scenario for a Java program is when already warm after boot up and code already JIT compiled. Using Linux time program to calculate the period from the cold boot is not a real world scenario because JVM needs some time during initialization I mean before executing the code. You better add a time measurement code withing each example to bypass the effects of cold boot.
Are you calculating compile time along with runtime for go but only runtime for java?