Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #80831 > unrolled thread

Strange result with timeit execution time measurment

Started by"ast" <nomail@invalid.com>
First post2014-11-15 18:07 +0100
Last post2014-11-15 11:18 -0700
Articles 5 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  Strange result with timeit execution time measurment "ast" <nomail@invalid.com> - 2014-11-15 18:07 +0100
    Re: Strange result with timeit execution time measurment Peter Pearson <pkpearson@nowhere.invalid> - 2014-11-15 18:12 +0000
    Re:Strange result with timeit execution time measurment Dave Angel <davea@davea.name> - 2014-11-15 13:08 -0500
    Re: Strange result with timeit execution time measurment Peter Otten <__peter__@web.de> - 2014-11-15 18:59 +0100
    Re: Strange result with timeit execution time measurment Ian Kelly <ian.g.kelly@gmail.com> - 2014-11-15 11:18 -0700

#80831 — Strange result with timeit execution time measurment

From"ast" <nomail@invalid.com>
Date2014-11-15 18:07 +0100
SubjectStrange result with timeit execution time measurment
Message-ID<54678857$0$2325$426a74cc@news.free.fr>
Hi

I needed a function f(x) which looks like sinus(2pi.x) but faster.
I wrote this one:

--------------------------
from math import floor

def sinusLite(x):
    x = x - floor(x)
    return -16*(x-0.25)**2 + 1 if x < 0.5 else 16*(x-0.75)**2 - 1
--------------------------

then i used module timeit to compare its execution time with math.sin()
I put the sinusLite() function in a module named test.

then:

>>> import timeit
>>> t1 = timeit.Timer("y=test.sinusLite(0.7)", "import test")
>>> t2 = timeit.Timer("y=math.sin(4.39)", "import math")        ## 4.39 = 2*pi*0.7

>>>  t1.repeat(3, 1000000)
[1.9994622221539373, 1.9020670224846867, 1.9191573230675942]

>>> t2.repeat(3, 1000000)
[0.2913627989031511, 0.2755561810230347, 0.2755186762562971]

so the genuine sinus is much faster than my so simple sinLite() !
Amazing isnt it ? Do you have an explanation ?

Thx

[toc] | [next] | [standalone]


#80834

FromPeter Pearson <pkpearson@nowhere.invalid>
Date2014-11-15 18:12 +0000
Message-ID<ccpjd4Ff1m9U1@mid.individual.net>
In reply to#80831
On Sat, 15 Nov 2014 18:07:30 +0100, ast wrote:
>
> I needed a function f(x) which looks like sinus(2pi.x) but faster.
> I wrote this one:
>
> --------------------------
> from math import floor
>
> def sinusLite(x):
>     x = x - floor(x)
>     return -16*(x-0.25)**2 + 1 if x < 0.5 else 16*(x-0.75)**2 - 1
> --------------------------
>
> then i used module timeit to compare its execution time with math.sin()
> I put the sinusLite() function in a module named test.
>
> then:
>
>>>> import timeit
>>>> t1 = timeit.Timer("y=test.sinusLite(0.7)", "import test")
>>>> t2 = timeit.Timer("y=math.sin(4.39)", "import math")   ## 4.39 = 2*pi*0.7
>
>>>>  t1.repeat(3, 1000000)
> [1.9994622221539373, 1.9020670224846867, 1.9191573230675942]
>
>>>> t2.repeat(3, 1000000)
> [0.2913627989031511, 0.2755561810230347, 0.2755186762562971]
>
> so the genuine sinus is much faster than my so simple sinLite() !
> Amazing isnt it ? Do you have an explanation ?

I suppose math.sin is implemented in C.  Compiled languages (like C) are
much faster than interpreted languages like Python.

-- 
To email me, substitute nowhere->runbox, invalid->com.

[toc] | [prev] | [next] | [standalone]


#80835

FromDave Angel <davea@davea.name>
Date2014-11-15 13:08 -0500
Message-ID<mailman.15855.1416075286.18130.python-list@python.org>
In reply to#80831
"ast" <nomail@invalid.com> Wrote in message:
> Hi
> 
> I needed a function f(x) which looks like sinus(2pi.x) but faster.
> I wrote this one:
> 
> --------------------------
> from math import floor
> 
> def sinusLite(x):
>     x = x - floor(x)
>     return -16*(x-0.25)**2 + 1 if x < 0.5 else 16*(x-0.75)**2 - 1
> --------------------------
> 
> then i used module timeit to compare its execution time with math.sin()
> I put the sinusLite() function in a module named test.
> 
> then:
> 
>>>> import timeit
>>>> t1 = timeit.Timer("y=test.sinusLite(0.7)", "import test")
>>>> t2 = timeit.Timer("y=math.sin(4.39)", "import math")        ## 4.39 = 2*pi*0.7
> 
>>>>  t1.repeat(3, 1000000)
> [1.9994622221539373, 1.9020670224846867, 1.9191573230675942]
> 
>>>> t2.repeat(3, 1000000)
> [0.2913627989031511, 0.2755561810230347, 0.2755186762562971]
> 
> so the genuine sinus is much faster than my so simple sinLite() !
> Amazing isnt it ? Do you have an explanation ?
> 
> Thx
> 

Sure, the library function probably used the trig logic in the
 processor. 
Perhaps if you timed things on a processor without a
 "math coprocessor" things could be different.  But even there,
 you'd probably be comparing C to python. Library code is
 optimized where it's deemed helpful. 

-- 
DaveA

[toc] | [prev] | [next] | [standalone]


#80836

FromPeter Otten <__peter__@web.de>
Date2014-11-15 18:59 +0100
Message-ID<mailman.15854.1416075286.18130.python-list@python.org>
In reply to#80831
ast wrote:

> Hi
> 
> I needed a function f(x) which looks like sinus(2pi.x) but faster.
> I wrote this one:
> 
> --------------------------
> from math import floor
> 
> def sinusLite(x):
>     x = x - floor(x)
>     return -16*(x-0.25)**2 + 1 if x < 0.5 else 16*(x-0.75)**2 - 1
> --------------------------
> 
> then i used module timeit to compare its execution time with math.sin()
> I put the sinusLite() function in a module named test.
> 
> then:
> 
>>>> import timeit
>>>> t1 = timeit.Timer("y=test.sinusLite(0.7)", "import test")
>>>> t2 = timeit.Timer("y=math.sin(4.39)", "import math")        ## 4.39 =
>>>> 2*pi*0.7
> 
>>>>  t1.repeat(3, 1000000)
> [1.9994622221539373, 1.9020670224846867, 1.9191573230675942]
> 
>>>> t2.repeat(3, 1000000)
> [0.2913627989031511, 0.2755561810230347, 0.2755186762562971]
> 
> so the genuine sinus is much faster than my so simple sinLite() !
> Amazing isnt it ? Do you have an explanation ?

You are applying your optimisation in an implementation where the function 
call overhead of a Python-implemented function is greater than the time to 
invoke the C-coded function, calculate the sin, and create the python float.

$ python -m timeit -s 'from math import sin' 'sin(.7)'
1000000 loops, best of 3: 0.188 usec per loop
$ python -m timeit -s 'from test import sinusLite as sin' 'sin(.7)'
1000000 loops, best of 3: 0.972 usec per loop
$ python -m timeit -s 'sin = lambda x: None' 'sin(.7)'
1000000 loops, best of 3: 0.242 usec per loop

For CPython to write fast lowlevel code you have to switch to C (or Cython).
In PyPy the results get interesting:

$ pypy -m timeit -s 'from test import sinusLite as sin' 'sin(.7)'
100000000 loops, best of 3: 0.00459 usec per loop
$ pypy -m timeit -s 'from math import sin' 'sin(.7)'
10000000 loops, best of 3: 0.0476 usec per loop

So yes, your approximation may speed up code in some parts of the Python 
universe (I don't know if pypy takes advantage of the constant argument).

[toc] | [prev] | [next] | [standalone]


#80837

FromIan Kelly <ian.g.kelly@gmail.com>
Date2014-11-15 11:18 -0700
Message-ID<mailman.15856.1416075531.18130.python-list@python.org>
In reply to#80831
On Sat, Nov 15, 2014 at 10:07 AM, ast <nomail@invalid.com> wrote:
> Hi
>
> I needed a function f(x) which looks like sinus(2pi.x) but faster.
> I wrote this one:
>
> --------------------------
> from math import floor
>
> def sinusLite(x):
>    x = x - floor(x)
>    return -16*(x-0.25)**2 + 1 if x < 0.5 else 16*(x-0.75)**2 - 1
> --------------------------
>
> then i used module timeit to compare its execution time with math.sin()
> I put the sinusLite() function in a module named test.
>
> then:
>
>>>> import timeit
>>>> t1 = timeit.Timer("y=test.sinusLite(0.7)", "import test")
>>>> t2 = timeit.Timer("y=math.sin(4.39)", "import math")        ## 4.39 =
>>>> 2*pi*0.7
>
>
>>>>  t1.repeat(3, 1000000)
>
> [1.9994622221539373, 1.9020670224846867, 1.9191573230675942]
>
>>>> t2.repeat(3, 1000000)
>
> [0.2913627989031511, 0.2755561810230347, 0.2755186762562971]
>
> so the genuine sinus is much faster than my so simple sinLite() !
> Amazing isnt it ? Do you have an explanation ?

The built-in sin is written in C, and the C implementation on most
modern systems boils down to a single assembly instruction implemented
in microcode. That's generally going to be faster than a whole series
of operations written in Python. Even just doing the 2*pi
multiplication in Python will add a lot to the timing:

C:\>python -m timeit -s "import math" "math.sin(2*math.pi*0.7)"
1000000 loops, best of 3: 0.587 usec per loop

C:\>python -m timeit -s "import math" "math.sin(4.39)"
1000000 loops, best of 3: 0.222 usec per loop

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web