leonardo ([info]leonardo_m) wrote,
@ 2009-02-03 14:56:00
Previous Entry  Add to memories!  Tell a Friend  Next Entry
Entry tags:benchmark, java, programming, python

Multiprecision integers
Built-in Python multiprecision integers (long) are handy but they aren't know for their speed. If you want speed you usually go with GMPY (http://gmpy.sourceforge.net/ ). I was curious to see how much slower are such numbers compared to the BigInteger of a common JavaVM.

So I have compared the multiplication efficienty (I think mutiplications aren't done much efficiently in Python long) with a basic program:

// Java code
import java.math.BigInteger;
public class Fact {
    public static void main() {
        BigInteger n = BigInteger.ONE;
        for (int i = 1; i <= 20000; i++)
            n = n.multiply(BigInteger.valueOf(i));
    }
}


// Python code #1
def main():
    n = 1
    for i in xrange(1, 20000+1):
        n *= i
main()


// Python code #2
from gmpy import mpz
def main():
    n = mpz(1)
    for i in xrange(1, 20000+1):
        n *= i
main()


// Python code #3
from gmpy import mpz
import psyco
def main():
    n = mpz(1)
    for i in xrange(1, 20000+1):
        n *= i
psyco.bind(main)
main()


// Python code #4
from gmpy import fac
fac(20000)


// D + Tango
import tango.math.BigInt: BigInt;
void main() {
    BigInt n = "1";
    for (int i = 1; i <= 20_000; i++)
        n *= i;
}

Timings:
  Java:    15.59 s
  Python1:  4.51 s
  D:        4.20 s 
  Python2:  1.66 s
  Python3:  1.23 s  
  Python4:  0.31 s

Notes on the D code:
- At the end the number 'n' is represented in 32116 bytes.
- I'd like to initialize n with a normal integral value, and not a string: BigInt n = 1;
- To print n you have to use (on Tango) something like: Cout(n.toDecimalString).newline; this is ugl, it needs a toString() for simple purposes (plus other things for more complex purposes).

CPU used: Pentium III 500 MHz.

VM/compiler/libs used:
- Python 2.5.2
- GMPY V.1.02
- java version "1.6.0_10"
- LDC D compiler with V.0.9 (rev 877) based on DMD v1.039 and llvm 2.4, with Tango.

The results of Python1 vs Java have surprised me, is someone able to explain them?



(Read 7 comments) - (Post a new comment)


[info]leonardo_m
2009-02-05 11:15 pm UTC (link)
(because honestly who gives a crap about vm startup in production code)

Generalizations are often silly or wrong. If my 'production code' works correctly and it has a running time of 5 minutes or 5 hours, then I agree that startup time isn't interesting.

But if I want to create some utility program that may have 5-10 seconds of total running time, then a fast start up is important. I have created many of such programs.

A fast start up is also useful for unit testing: I have a "large" D code (about 60000 lines or more) that has thousands of unit tests. Despite their number, all such such tests run in a bit more than on second on a 2 GHz Core Duo CPU. The DMD D compiler is also quite fast, compiling all such code in very few seconds. In such situation having a slow startup time isn't good, it may slow down your unit testing.

(Reply to this) (Parent)


(Read 7 comments) - (Post a new comment)

Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…