Basic question about speed/coding style/memory
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Sat Jul 21 05:06:40 EDT 2012
On Sat, 21 Jul 2012 10:33:27 +0300, Jan Riechers wrote:
> Hello Pythonlist,
>
> I have one very basic question about speed,memory friendly coding, and
> coding style of the following easy "if"-statement in Python 2.7, but Im
> sure its also the same in Python 3.x
I assume that the following is meant to be inside a function, otherwise
the return in the second example is illegal.
But in general, you're worrying too much about trivia. One way or the
other, any speed difference will be trivial. Write whatever style reads
and writes most naturally, and only worry about what's faster where it
actually counts.
To give it an analogy that might be clear, this question is not too far
from worrying about whether your car will be faster with the radio aerial
up or down. Yes, technically the car will be slower with the aerial up,
due to air resistance, but you'd have a job measuring it, and it makes no
difference whether you are zooming down the highway at 120mph or stuck in
traffic crawling along at 5mph.
Here's a minimal example:
def with_else(x):
if x:
a = x
else:
a = x+1
return a
def without_else(x):
if x:
a = x
return a
a = x+1
return a
Notice that I try to make each function do the same amount of work, so
that we're seeing only the difference between "else" vs "no else".
Now let's test the speed difference with Python 2.7. Because this is
timing small code snippets, we should use the timeit module to time the
code:
from timeit import Timer
setup = "from __main__ import with_else, without_else"
t1 = Timer("for i in (0, 1): result = with_else(i)", setup)
t2 = Timer("for i in (0, 1): result = without_else(i)", setup)
Each snippet calls the function twice, once to take the if branch, then
to take the else branch.
Now we time how long it takes to run each code snippet 1000000 times. We
do that six times each, and print the best (lowest) speed:
py> min(t1.repeat(repeat=6))
0.9761919975280762
py> min(t2.repeat(repeat=6))
0.9494419097900391
So there is approximately 0.03 second difference per TWO MILLION
if...else blocks, or about 15 nanoseconds each. This is highly unlikely
to be the bottleneck in your code. Assuming the difference is real, and
not just measurement error, the difference is insignificant.
So, don't worry about which is faster. Write whichever is more natural,
easier to read and write.
> Block
> #----------------------------------
> if statemente_true:
> doSomething()
> else:
> doSomethingElseInstead()
This style is especially recommended when the two clauses are equal in
importance.
> versus this block:
> #----------------------------------
> if statement_true:
> doSomething()
> return
> doSomethingElseInstead()
This style is especially recommended when the doSomethingElseInstead()
block is the "normal" procedure, and the doSomething() block is a special
case. Not necessarily rare, but nevertheless special in some sense.
Of course, the decision as to which is the "special" case and which is
the "normal" case is often entirely arbitrary.
--
Steven
More information about the Python-list
mailing list