map del efficiency python2.2 and 2.1
Andrew McNamara
andrewm at object-craft.com.au
Wed Jul 17 00:11:33 EDT 2002
>This is exactly the kind of "seemingly random disaster" we see when the
>platform free() goes nuts, although it's usually much more pronounced than a
>measly factor of 2. If so, rebuilding with pymalloc is likely to fix it,
>while if you don't you'll never answer "why?" without a deep understanding
>of your platform C's implementation of free().
I recently got curious about the relative performance of various python
versions, new style classes and slots. I wrote a very simple benchmark
that allocated and deallocated a million small objects on a 600MHz P3
running linux 2.4.18 and glibc-2.2.4 with enough memory to prevent paging.
Results and code are below. It's clear that the system malloc hurts
badly for deallocation, but even with pymalloc deallocation is still
an expensive exercise (the attribute dictionary, presumably). Slots are
very efficient for small objects, in terms of CPU and memory footprint.
Create and
set attr Set attr Del+GC RSS
-------- -------- -------- -------
py22 slots 20.3s 4.6s 19.5s 48M
py221 slots 21.0s 5.0s 21.5s 48M
pymalloc slots 16.2s 4.7s 0.7s 40M
py22 obj 65.9s 7.4s 401.5s 185M
py221 obj 62.1s 7.3s 492.8s 185M
pymalloc obj 57.9s 7.2s 125.8s 185M
py22 trad 55.8s 6.8s 275.8s 192M
py221 trad 56.8s 7.1s 284.7s 192M
pymalloc trad 52.6s 6.8s 115.0s 185M
py211 trad 52.6s 6.6s 239.4s 154M
With gc.disable(), and explicitly calling gc.collect():
Create and
set attr Set attr Del+GC RSS
-------- -------- -------- -------
py22 slots 13.6s 4.6s 19.7s 48M
py221 slots 14.0s 5.0s 19.4s 48M
pymalloc slots 10.6s 4.7s 0.7s 40M
py22 obj 18.0s 7.3s 400.5s 185M
py221 obj 18.7s 7.6s 399.0s 185M
pymalloc obj 16.2s 7.2s 117.0s 185M
py22 trad 11.2s 6.8s 270.8s 192M
py221 trad 12.1s 7.2s 240.7s 192M
pymalloc trad 11.4s 6.8s 115.3s 185M
py211 trad 11.6s 6.5s 229.0s 154M
py152 trad 7.8s 3.1s 75.5s 123M
KEY
------ -----------------------------------------------------------
slots with new-style objects and using slots
obj with new-style objects
trad with traditional objects
py22 Python 2.2
py221 Python 2.2.1
pymalloc Python 2.2.1 compiled with --with-pymalloc
py211 Python 2.1.1 with traditional objects
py152 Python 1.5.2 with traditional objects (no cyclic-GC)
----------------------------------------------------------------------------
import time, gc
iters = 1000000
def start():
global ts
ts = time.time()
def stop(msg):
delta = time.time() - ts
if delta < 0.00001:
print msg, "took %.1fus" % (delta * 1000000)
elif delta < 0.01:
print msg, "took %.1fms" % (delta * 1000)
else:
print msg, "took %.1fs" % (delta)
try:
class slots(object):
__slots__ = ('a')
def __init__(self, n):
self.a = n
def set(self, x):
self.a = x
class obj(object):
def __init__(self, n):
self.a = n
def set(self, x):
self.a = x
except NameError:
pass
class trad:
def __init__(self, n):
self.a = n
def set(self, x):
self.a = x
def testit(ctor, count):
print "testing", ctor.__name__
start()
a = map(ctor, xrange(count))
gc.collect()
stop(' create + setattr')
start()
aa = ctor(0)
map(aa.set, xrange(count))
gc.collect()
stop(' setattr')
start()
del a
gc.collect()
stop(' del')
if 0:
gc.disable()
if 0:
testit(slots, iters)
if 0:
testit(obj, iters)
if 1:
testit(trad, iters)
--
Andrew McNamara, Senior Developer, Object Craft
http://www.object-craft.com.au/
More information about the Python-list
mailing list