dynamism
Duncan Booth
duncan at NOSPAMrcp.co.uk
Wed Sep 11 04:13:24 EDT 2002
"Steven Shaw" <steven_shaw at iprimus.com.au> wrote in
news:3d7e209a_1 at news.iprimus.com.au:
> Does this mean that the attributes are stored in a more efficient way?
>
> Is there a way to implement "record-based" object layout rather than
> "associative-array based" object layout?
>
>
It very much depends what you mean by 'more efficient'. Using object-
derived classes and __slots__ means that each class no longer has the
overhead of creating a dictionary for the instance attributes, so you are
saving the memory overhead of the dictionary. On the other hand, object-
derived classes seem to be slower to create, and setting attributes defined
in object-derived classes is also slower than setting attributes in old-
style classes (although setting __slots__ attributes seems to be faster
than setting other attributes).
The code below gives these timings on my machine:
3.84s: 1000000 x New()
3.89s: 1000000 x New2()
2.39s: 1000000 x Old()
5.19s: 10000 x attributes(<class '__main__.New'>)
5.81s: 10000 x attributes(<class '__main__.New2'>)
4.17s: 10000 x attributes(__main__.Old)
--------------------------------
class Old: pass
class New(object):
__slots__ = ['a', 'b', 'c', 'd']
# New-style, but not using slots.
class New2(object): pass
def timeit(repeat, fn, *args, **kw):
import time
start = time.time()
for i in xrange(repeat):
fn(*args, **kw)
end = time.time()
# Format arguments for printout
argstring = ', '.join(
[str(a) for a in args] +
[ '%s=%s' % (k, v) for k, v in kw.items()])
if len(argstring) > 60:
argstring = argstring[:57] + '...'
print "%.2fs: %d x %s(%s)" % ((end-start), repeat, fn.__name__,
argstring)
def attributes(klass):
inst = klass()
inst.a = 1
for i in range(100):
inst.b = inst.a+1
inst.c = inst.a+2
inst.d = inst.a+4
inst.a += 5
timeit(1000000, New)
timeit(1000000, New2)
timeit(1000000, Old)
timeit(10000, attributes, New)
timeit(10000, attributes, New2)
timeit(10000, attributes, Old)
--------------------------------
--
Duncan Booth duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
More information about the Python-list
mailing list