[IronPython] More Performance comparisons - dictionary updates and tuples
Michael Foord
fuzzyman at voidspace.org.uk
Wed Apr 16 19:32:36 CEST 2008
Hello guys,
I've been looking at performance in Resolver One. (Object creation in
IronPython seems to be really good whereas dictionary lookups not so
good when we compare against CPython.)
It turns out that we are getting bitten quite badly by the performance
of hashing tuples (fixing this for IP 1.1.2 would be *great*). I did
some profiling and have some comparisons - and can also show a
regression in performance in IP 2 (Beta 1) when using ints as dictionary
keys in an update operation. I thought I would post the results as they
may be useful.
(Dictionary update in IP 1 with tuple keys is an order of magnitude
slower than CPython. So is IP 2 but still twice as good as IP 1 - two
times *worse* than IP 1 for tuple creating and unpacking though.)
Results first:
CPython
e:\Dev>timeit1.py
tuple_create_and_unpack took 220.999956131 ms
dict_update took 541.000127792 ms
IP 1.1.1
e:\Dev>e:\Dev\ironpython1\ipy.exe timeit1.py
tuple_create_and_unpack took 680.9792 ms
dict_update took 7891.3472 ms
IP 2 Beta 1
e:\Dev>e:\Dev\ironpython2\ipy.exe timeit1.py
tuple_create_and_unpack took 1341.9296 ms
dict_update took 4756.84 ms
If we switch to using integers rather than tuples for the dictionary
keys, the performance changes:
CPython
e:\Dev>timeit1.py
tuple_create_and_unpack took 200.000047684 ms
dict_update took 230.999946594 ms
IP 1.1.1
e:\Dev>e:\Dev\ironpython1\ipy.exe timeit1.py
tuple_create_and_unpack took 911.3104 ms
dict_update took 420.6048 ms
IP 2 Beta 1
e:\Dev>e:\Dev\ironpython2\ipy.exe timeit1.py
tuple_create_and_unpack took 971.3968 ms
dict_update took 1582.2752 ms
With ints as keys, IP 1 is only half the speed of CPython - but IP 2 is
four times slower than IP 1!
The code used - which runs under both CPython and IronPython
from random import random
try:
import clr
from System import DateTime
def timeit(func):
start = DateTime.Now
func()
end = DateTime.Now
print func.__name__, 'took %s ms' % (end - start).TotalMilliseconds
except ImportError:
import time
def timeit(func):
start = time.time()
func()
end = time.time()
print func.__name__, 'took %s ms' % ((end - start) * 1000)
def tuple_create_and_unpack():
for val in range(1000000):
a, b = val, val + 1
d1 = {}
for x in range(100):
for y in range(100):
d1[x, y] = random()
d2 = {}
for x in range(1000):
for y in range(1000):
d2[x, y] = random()
def dict_update():
d1.update(d2)
timeit(tuple_create_and_unpack)
timeit(dict_update)
Michael Foord
http://www.ironpythoninaction.com/
More information about the Ironpython-users
mailing list