By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,050 Members | 1,009 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,050 IT Pros & Developers. It's quick & easy.

Basic optimization of python.

P: n/a
Howdy,
I wonder whether python compiler does basic optimizations to .py.
Eg:
t = self.a.b
t.c = ...
t.d = ...
..vs.
self.a.b.c = ...
self.a.b.d = ...
which one is more effective? Since each dot invokes a hash table lookup, it
may be time consuming. If the compiler can do expression folding, then no
manual folding is needed.

Again, how about contant calculation?
Eg:
a = 1 + 2
..vs.
a = 3
which one is more effective? Does the compiler calculate the result at
compile time? How about constant spreading?

Best regards,
---
ShenLei

Apr 9 '08 #1
Share this Question
Share on Google+
7 Replies


P: n/a
甜瓜 wrote:
Howdy,
I wonder whether python compiler does basic optimizations to .py.
Eg:
t = self.a.b
t.c = ...
t.d = ...
.vs.
self.a.b.c = ...
self.a.b.d = ...
which one is more effective? Since each dot invokes a hash table lookup,
it may be time consuming. If the compiler can do expression folding, then
no manual folding is needed.

It can't do that because of no guarantee can be made that self.a has no
side-effects, and consequently doesn't do it.
Again, how about contant calculation?
Eg:
a = 1 + 2
.vs.
a = 3
which one is more effective? Does the compiler calculate the result at
compile time? How about constant spreading?
Algebraic optimizations aren't done AFAIK - and it's debatable if the
mu-secs saved by that would be worth the effort, as if *they* matter, you
obviously are in number-crunching mode and should resort to libs such as
Numpy to do your work.

Diez
Apr 9 '08 #2

P: n/a
On Apr 7, 7:30 am, "" <littlesweetme...@gmail.comwrote:
Howdy,
I wonder whether python compiler does basic optimizations to .py.
Eg:
t = self.a.b
t.c = ...
t.d = ...
.vs.
self.a.b.c = ...
self.a.b.d = ...
which one is more effective? Since each dot invokes a hash table lookup, it
may be time consuming. If the compiler can do expression folding, then no
manual folding is needed.
The compiler can not simply do such folding, as just the act of
looking up an attribute can have all kinds of side effects via the
methods __getattr__ and __getattribute__ . So the second time you look
up self.a the value can differ from the first time, or the attribute
may not exist anymore!
Again, how about contant calculation?
Eg:
a = 1 + 2
.vs.
a = 3
which one is more effective? Does the compiler calculate the result at
compile time? How about constant spreading?
This is safe, and is done:
>>import dis
def f(): x = 1 + 2
...
>>dis.dis(f)
1 0 LOAD_CONST 3 (3)
3 STORE_FAST 0 (x)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
>>>
- Willem
Apr 9 '08 #3

P: n/a
"Diez B. Roggisch" <de***@nospam.web.dewrites:
>Eg:
a = 1 + 2
.vs.
a = 3
which one is more effective? Does the compiler calculate the result at
compile time? How about constant spreading?

Algebraic optimizations aren't done AFAIK
Just try it:

Python 2.5.1 (r251:54863, Oct 5 2007, 13:36:32)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>dis.dis(lambda: 10+5)
1 0 LOAD_CONST 2 (15)
3 RETURN_VALUE
Apr 9 '08 #4

P: n/a
This is safe, and is done:
>
>>>import dis
def f(): x = 1 + 2
...
>>>dis.dis(f)
1 0 LOAD_CONST 3 (3)
3 STORE_FAST 0 (x)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
>>>>
So I stand corrected. Any idea when that was introduced?

Diez
Apr 9 '08 #5

P: n/a
Hrvoje Niksic wrote:
"Diez B. Roggisch" <de***@nospam.web.dewrites:
>>Eg:
a = 1 + 2
.vs.
a = 3
which one is more effective? Does the compiler calculate the result at
compile time? How about constant spreading?

Algebraic optimizations aren't done AFAIK

Just try it:

Python 2.5.1 (r251:54863, Oct 5 2007, 13:36:32)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>dis.dis(lambda: 10+5)
1 0 LOAD_CONST 2 (15)
3 RETURN_VALUE
I remember times when that hasn't been the case - thus my answer.

[GCC 3.4.6 (Ubuntu 3.4.6-6ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Welcome to rlcompleter2 0.96
for nice experiences hit <tabmultiple times
>>import dis
dis.dis(lambda: 1+2)
1 0 LOAD_CONST 1 (1)
3 LOAD_CONST 2 (2)
6 BINARY_ADD
7 RETURN_VALUE
Python 2.4.4 (#2, Mar 7 2008, 04:45:43)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>import dis
dis.dis(lambda: 1+2)
1 0 LOAD_CONST 1 (1)
3 LOAD_CONST 2 (2)
6 BINARY_ADD
7 RETURN_VALUE
>>>

But great to know it is done now.

Diez
Apr 9 '08 #6

P: n/a
ShenLei:
t = self.a.b
t.c = ...
t.d = ...
.vs.
self.a.b.c = ...
self.a.b.d = ...
which one is more effective? Since each dot invokes a hash table lookup, it
may be time consuming. If the compiler can do expression folding, then no
manual folding is needed.
Removing dots creating a temporary variable speeds up the program, but
doing it is useful only in special critical spots, like inside certain
large loops, etc.
A similar optimization is to use a local instead of a global:

from foo import bar
def baz(bar=bar):
for i in xrange(100000):
bar(...)

Note that with psyco you often don't need such things.

Bye,
bearophile
Apr 9 '08 #7

P: n/a
In article <87************@mulj.homelinux.net>,
Hrvoje Niksic <hn*****@xemacs.orgwrote:
"Diez B. Roggisch" <de***@nospam.web.dewrites:
Eg:
a = 1 + 2
.vs.
a = 3
which one is more effective? Does the compiler calculate the result at
compile time? How about constant spreading?
Algebraic optimizations aren't done AFAIK

Just try it:

Python 2.5.1 (r251:54863, Oct 5 2007, 13:36:32)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>dis.dis(lambda: 10+5)
1 0 LOAD_CONST 2 (15)
3 RETURN_VALUE
Not always. On a Mac running Python 2.4, here's what I get:

In [3]: dis.dis(lambda: 3+4)
1 0 LOAD_CONST 1 (3)
3 LOAD_CONST 2 (4)
6 BINARY_ADD
7 RETURN_VALUE

--
-- Lou Pecora
Apr 9 '08 #8

This discussion thread is closed

Replies have been disabled for this discussion.