Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It's faster <em>and</em> more readable to construct the object and then attach it to <code>self</code>.</p> <pre><code>class Test1(object): def __init__(self): d = {} d['a'] = 1 d['b'] = 2 d['c'] = 3 self.d = d class Test2(object): def __init__(self): self.d = {} self.d['a'] = 1 self.d['b'] = 2 self.d['c'] = 3 import dis print "Test1.__init__" dis.dis(Test1.__init__) print "Test2.__init__" dis.dis(Test2.__init__) </code></pre> <p>disassemles to:</p> <pre><code>Test1.__init__ 4 0 BUILD_MAP 0 3 STORE_FAST 1 (d) 5 6 LOAD_CONST 1 (1) 9 LOAD_FAST 1 (d) 12 LOAD_CONST 2 ('a') 15 STORE_SUBSCR 6 16 LOAD_CONST 3 (2) 19 LOAD_FAST 1 (d) 22 LOAD_CONST 4 ('b') 25 STORE_SUBSCR 7 26 LOAD_CONST 5 (3) 29 LOAD_FAST 1 (d) 32 LOAD_CONST 6 ('c') 35 STORE_SUBSCR 8 36 LOAD_FAST 1 (d) 39 LOAD_FAST 0 (self) 42 STORE_ATTR 0 (d) 45 LOAD_CONST 0 (None) 48 RETURN_VALUE Test2.__init__ 12 0 BUILD_MAP 0 3 LOAD_FAST 0 (self) 6 STORE_ATTR 0 (d) 13 9 LOAD_CONST 1 (1) 12 LOAD_FAST 0 (self) 15 LOAD_ATTR 0 (d) 18 LOAD_CONST 2 ('a') 21 STORE_SUBSCR 14 22 LOAD_CONST 3 (2) 25 LOAD_FAST 0 (self) 28 LOAD_ATTR 0 (d) 31 LOAD_CONST 4 ('b') 34 STORE_SUBSCR 15 35 LOAD_CONST 5 (3) 38 LOAD_FAST 0 (self) 41 LOAD_ATTR 0 (d) 44 LOAD_CONST 6 ('c') 47 STORE_SUBSCR 48 LOAD_CONST 0 (None) 51 RETURN_VALUE </code></pre> <p>You can see that <code>STORE_ATTR</code> only gets called once doing it the first way at the end. Doing it the other way, <code>STORE_ATTR</code> still gets called right at the beginning but now <code>LOAD_ATTR</code> gets called for every access to the dictionary. The more assignments there are, the higher the cost. Every other instruction is the same. It's still a ridiculously small cost.</p> <p>This trick can be exploited to make loops with many iterations run faster. It's not uncommon to see things like</p> <pre><code>foo = self.foo factorial = math.factorial for x in really_big_iterator: foo(factorial(x)) </code></pre> <p>another trick is to pass global functions as default arguments to a function that has a loop like that or gets called a whole bunch to save some attribute lookups: it's in the local scope which is the first one looked in.</p> <pre><code>def fast(iterators, sum=sum): for i in iterator: yield sum(i) </code></pre> <p>now sum is right in the local scope.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload