[Tutor] Style question with classes and modules
Kent Johnson
kent37 at tds.net
Thu Jul 19 22:27:54 CEST 2007
Tino Dai wrote:
> Why do you expect a speedup?
>
>
> In the Python Reference by David Beazley on p. 40, he substituted
> import math
> with from math import sqrt and he switched out d = d + math.sqrt(i) with
> sqrt(i). He said that that change made the program run twice as fast.
> So therefore
> I was under the impression that "from somemodule import someclass" would
> always be
> faster than import somemodule.
Attribute access is somewhat expensive so if you can pull it out of a
critical loop you get a speedup.
import foo
foo.bar()
and
from foo import bar
bar()
will not have an appreciable difference in speed. OTOH
import foo
for i in range(10000):
foo.bar()
may be slower than
from foo import bar
for i in range(10000):
bar()
because the attribute access is essentially being hoisted outside the
loop so it only happens once.
You can also get a speedup by putting a loop into a function so critical
variables are found in the local namespace instead of the module namespace.
Attribute lookup seems to have gotten better since Beazley wrote; here
is a test program that uses three ways to access math.sqrt - module
attribute, global name, local name. Note that in the third version, all
three names (sqrt, d, i) are local:
###########################
import math
from time import time
start = time()
d = 0.0
for i in xrange(1000000):
d = d + math.sqrt(i)
duration = time() - start
print duration * 1000.
sqrt = math.sqrt
start = time()
d = 0.0
for i in xrange(1000000):
d = d + sqrt(i)
duration = time() - start
print duration * 1000.
def compute():
sqrt = math.sqrt
d = 0.0
for i in xrange(1000000):
d = d + sqrt(i)
start = time()
compute()
duration = time() - start
print duration * 1000.
################################
Sample output:
745.465993881
561.167001724
369.343996048
Another way to measure this is with the timeit module:
kent $ python -m timeit -s "import math" "math.sqrt(1)"
1000000 loops, best of 3: 0.361 usec per loop
kent $ python -m timeit -s "from math import sqrt" "sqrt(1)"
1000000 loops, best of 3: 0.293 usec per loop
timeit runs both the setup code and the code under test inside a
function so all the names are local in this case.
Kent
More information about the Tutor
mailing list