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

Discussion in 'Python' started by Markus, Jul 24, 2006.

  1. Markus

    Markus Guest

    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
     
    Markus, Jul 24, 2006
    #1
    1. Advertising

  2. Markus

    John Machin Guest

    Markus wrote:
    > 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
     
    John Machin, Jul 24, 2006
    #2
    1. Advertising

  3. Markus

    Paul McGuire Guest

    "John Machin" <> wrote in message
    news:...
    > Markus wrote:
    > > 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.
    > >

    <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-]


    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
     
    Paul McGuire, Jul 24, 2006
    #3
  4. Markus

    Georg Brandl Guest

    John Machin wrote:
    > Markus wrote:
    >> 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
     
    Georg Brandl, Jul 25, 2006
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. -
    Replies:
    3
    Views:
    401
  2. Gerrit Holl
    Replies:
    0
    Views:
    263
    Gerrit Holl
    Jan 15, 2004
  3. newswire_4_developers
    Replies:
    0
    Views:
    271
    newswire_4_developers
    Oct 28, 2005
  4. developer newswire
    Replies:
    0
    Views:
    346
    developer newswire
    Oct 21, 2005
  5. Tinxx
    Replies:
    13
    Views:
    341
    BartC
    Jun 10, 2013
Loading...

Share This Page