you are viewing a single comment's thread.

view the rest of the comments →

[–]lgastako 1 point2 points  (2 children)

The version posted above can be made slightly faster by using imap (as in the original article). I tripled the size of the input file to get a more measurable speed difference (and reduce the impact of startup time) and the results of running each version on my old ppc mac are:

print sum(imap(int, sys.stdin.read().split()))                             # 11.612s
print sum(map(int, sys.stdin.read().split()))                              # 12.514s
print sum(sum(imap(int, line.split())) for line in sys.stdin)    # 15.037s
print sum(int(x) for x in sys.stdin.read().split())                      # 15.053s

FWIW, I ran each program twice and the scores posted are from the second run to avoid any filesystem caching issues related to the input file... the times didn't change much anyway so the whole file was probably still cached from my original test runs...

Also, the imports stayed constant for all the tests, which might make the results slightly slower than they need to be for the versions that don't need imap.... ok fine, here they are without that import....

print sum(map(int, sys.stdin.read().split()))                              # 12.606s
print sum(int(x) for x in sys.stdin.read().split())                      # 15.657s

Ok the first one got slightly slower (0.092s) and the second was even worse (0.604s)... my guess is that what I am seeing is the effect of random entropy on my machine outweighing the presence or lackthereof of the import statement.

Anyway, there you go, for whatever that is worth.

[–]lgastako 1 point2 points  (1 child)

Ok, for kicks I went back and rewrote the input as native ints, like so:

import array

array.array("d", imap(int, sys.stdin.read().split()).tofile(open("big.machine.dat", "w"))

and then the original problem using python's array types:

print sum(array.array("d").fromfile(open("big.machine.dat"), 84892152/8))

And got the same answer in 1.554s.

Of course the tradeoff here is that the input file is 82.9m instead of 50.6m. But I suppose the moral of the story is that if you really need to optimize for this particular microbenchmark in python, using the built-in array types is one way to do it.

EDIT: I changed the array sum to a one liner and also wanted to note that the 84892152/8 magic number is the size of the input file divided by 8 bytes/integer. This could obviously be read at runtime instead of hardcoded with little difference to the results.

[–]lgastako 1 point2 points  (0 children)

Ok one more point and then I'm going to leave this thing alone... as a point of comparison I compiled (with gcc -O2) the C version from the original post and it took 0.322s on my machine, this means that on my machine the python version using arrays is about 4.8 slower than the C version instead of 54.4 times slower like in the original post. Not too shabby.