How can I optimise this? [intended in good humour]

M

Markus

You know you're guilty of early/over optimisation, when it's almost two
in the morning and the file open in front of you reads as follows.

The code you are about to read is real...
Some of the variable names have been changed
to protect the families of those involved.

[-snip-]

from timeit import Timer

if __name__=='__main__':
t = Timer('len(argv)==1','from sys import argv')
print "%f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
t = Timer('argv[0]==argv[-1]','from sys import argv')
print "%f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

[-snip-]

For anyone is in danger of making the same mistakes I've made...
the results were:

0.219154 usec/pass
0.297468 usec/pass


If anyone doesn't understand...
Timer is a "Class for timing execution speed of small code snippets."
The quoted description of Timer and the original code I derived the
above snippet from, can be found in the Python documentation.

Finally, for anyone who is wondering...
I will seek help as soon as I have some free time.

;)

Markus
 
J

John Machin

Markus said:
You know you're guilty of early/over optimisation, when it's almost two
in the morning and the file open in front of you reads as follows.

The code you are about to read is real...
Some of the variable names have been changed
to protect the families of those involved.

[-snip-]

from timeit import Timer

if __name__=='__main__':
t = Timer('len(argv)==1','from sys import argv')
print "%f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
t = Timer('argv[0]==argv[-1]','from sys import argv')
print "%f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

[-snip-]

For anyone is in danger of making the same mistakes I've made...
the results were:

0.219154 usec/pass
0.297468 usec/pass


If anyone doesn't understand...
Timer is a "Class for timing execution speed of small code snippets."
The quoted description of Timer and the original code I derived the
above snippet from, can be found in the Python documentation.

Finally, for anyone who is wondering...
I will seek help as soon as I have some free time.

Do you realise that the two expressions that you are comparing are not
even equivalent, and moreover you ignored an expression that will be
faster and equivalent (unless/until somebody decides on an
"optimisation" like interning/sharing strings between/among sys.argv
elements).

C:\junk>type showargs.py
from sys import argv
print argv, len(argv)==1, argv[0]==argv[-1], argv[0] is argv[-1]

C:\junk>showargs.py C:\junk\showargs.py
['C:\\junk\\showargs.py', 'C:\\junk\\showargs.py'] False True False

C:\junk>python -mtimeit -s"a=['jabberwocky','jabber'+'wocky']"
"len(a)==1"
1000000 loops, best of 3: 0.142 usec per loop

C:\junk>python -mtimeit -s"a=['jabberwocky','jabber'+'wocky']"
"a[0]==a[-1]"
1000000 loops, best of 3: 0.191 usec per loop

C:\junk>python -mtimeit -s"a=['jabberwocky','jabber'+'wocky']" "a[0] is
a[-1]"
10000000 loops, best of 3: 0.135 usec per loop

C:\junk>python -mtimeit -s"a=['jabberwocky']" "len(a)==1"
1000000 loops, best of 3: 0.132 usec per loop

C:\junk>python -mtimeit -s"a=['jabberwocky']" "a[0]==a[-1]"
1000000 loops, best of 3: 0.14 usec per loop

C:\junk>python -mtimeit -s"a=['jabberwocky']" "a[0] is a[-1]"
1000000 loops, best of 3: 0.111 usec per loop

Cheers,
John
 
P

Paul McGuire

John Machin said:
Markus said:
You know you're guilty of early/over optimisation, when it's almost two
in the morning and the file open in front of you reads as follows.
from timeit import Timer

if __name__=='__main__':
t = Timer('len(argv)==1','from sys import argv')
print "%f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
t = Timer('argv[0]==argv[-1]','from sys import argv')
print "%f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

[-snip-]

You're worried about the performance of len(sys.argv)?! Is your command line
processing *really* your program bottleneck? If so, I'd say making a better
len is the least of your problems.

Hard to imagine you'll do better than len, especially for lists as short as
command line args. If you are *really* doing lots of len'ning, copy len to
a local to cut down on lookup costs:

C:\Documents and Settings\Paul>python -mtimeit -s"a=['abc','abc']" "len(a)"
1000000 loops, best of 3: 0.218 usec per loop

C:\Documents and Settings\Paul>python -mtimeit -s"a=['abc','abc'];len_=len"
"len_(a)"
10000000 loops, best of 3: 0.172 usec per loop

But honestly, do some profiling before adding these maintenance-hindering
and readability-impairing "optimizations."

-- Paul
 
G

Georg Brandl

John said:
Markus said:
You know you're guilty of early/over optimisation, when it's almost two
in the morning and the file open in front of you reads as follows.

The code you are about to read is real...
Some of the variable names have been changed
to protect the families of those involved.

[-snip-]

from timeit import Timer

if __name__=='__main__':
t = Timer('len(argv)==1','from sys import argv')
print "%f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
t = Timer('argv[0]==argv[-1]','from sys import argv')
print "%f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
Do you realise that the two expressions that you are comparing are not
even equivalent, and moreover you ignored an expression that will be
faster and equivalent (unless/until somebody decides on an
"optimisation" like interning/sharing strings between/among sys.argv
elements).

Let me point out that len(argv) == 1 is the only one that will work if
argv is []. ;) (took me a few seconds to realize I must put a smiley there)

Georg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,192
Latest member
KalaReid2

Latest Threads

Top