Numpy slow at vector cross product?

BartC bc at freeuk.com
Tue Nov 22 08:06:05 EST 2016


On 22/11/2016 03:00, Steve D'Aprano wrote:
> On Tue, 22 Nov 2016 12:45 pm, BartC wrote:

>> You get to know after while what kinds of processes affect timings. For
>> example, streaming a movie at the same time.
>
> Really, no.

> py> with Stopwatch():
> ...     x = math.sin(1.234)
> ...
> elapsed time is very small; consider using the timeit module for
> micro-timings of small code snippets
> time taken: 0.007164 seconds

I tried 'Stopwatch()' and it didn't understand what it was.

> And again:
>
> py> with Stopwatch():
> ...     x = math.sin(1.234)
> ...
> elapsed time is very small; consider using the timeit module for
> micro-timings of small code snippets
> time taken: 0.000014 seconds
>
>
> Look at the variation in the timing: 0.007164 versus 0.000014 second. That's
> the influence of a cache, or more than one cache, somewhere. But if I run
> it again:
>
> py> with Stopwatch():
> ...     x = math.sin(1.234)
> ...
> elapsed time is very small; consider using the timeit module for
> micro-timings of small code snippets
> time taken: 0.000013 seconds
>
> there's a smaller variation, this time "only" 7%, for code which hasn't
> changed. That's what your up against.

I tried this:

import math

def fn():
	for i in xrange(3000000):
		x=math.sin(1.234)
	print x

fn()

If I run this, my IDE tells me the whole thing took 0.93 seconds. That's 
including the overheads of the IDE, invoking python.exe, Python's 
start-up time, the function call, the loop overheads, and whatever is 
involved in shutting it all down again.

Now I replace the x=math.sin() line with pass. The IDE now says 0.21 
seconds. The only thing that's changed is the sin() call. I can probably 
deduce that executing x=math.sin(1.2340) three million times took 0.72 
seconds (with some expected variation).

So over 4 million times per second. Which is interesting because your 
timings with Stopwatch varied from 140 to 71000 per second (and I doubt 
your machine is that much slower than mine).


> [steve at ando ~]$ python2.7 -m timeit -s "x = 257" "3*x"
> 10000000 loops, best of 3: 0.106 usec per loop
> [steve at ando ~]$ python3.5 -m timeit -s "x = 257" "3*x"
> 10000000 loops, best of 3: 0.137 usec per loop

> That's *brilliant* and much simpler than anything you are doing with loops
> and clocks and whatnot.

But you lose all context. And there is a limit to what you can do with 
such micro-benchmarks.

Sometimes you want to time a real task, but with one line substituted 
for another, or some other minor rearrangement.

Or perhaps the overall time of a code fragment depends on the mix of 
data it has to deal with.

>> Code will normally exist as a proper part of a module, not on the
>> command line, in a command history, or in a string, so why not test it
>> running inside a module?
>
> Sure, you can do that, if you want potentially inaccurate results.

When your customer runs your application (and complains about how long 
it takes), they will be running the code as normal not inside a string 
or on the command line!

> In this specific example, the OP is comparing two radically different pieces
> of code that clearly and obviously perform differently. He's doing the
> equivalent of timing the code with his heartbeat, and getting 50 beats for
> one and 150 beats for the other. That's good enough to show gross
> differences in performance.

No, he's using time.clock() with, presumably, a consistent number of 
ticks per second.

> But often you're comparing two code snippets which are very nearly the same,
> and trying to tease out a real difference of (say) 3% out of a noisy signal
> where each run may differ by 10% just from randomness. Using your heartbeat
> to time code is not going to do it.

Yes, exactly, that's why typing a code fragment on the command line is a 
waste of time. You need to design a test where the differences are going 
to be more obvious.

-- 
Bartc



More information about the Python-list mailing list