KristoferMarG
KristoferMarG

Reputation: 43

Why is it that np.dot is so much faster than finding the dot product using for-loops

Here is the time using np.dot:

import numpy as np
import timeit

x = np.random.random(size=10**7)
a = np.ones(x.size)

%time np.dot(x, a)

Wall time: 11 ms

5001679.267011214

Here is the time using for-loops:

import numpy as np
import timeit

x = np.random.random(size=10**7)
a = np.ones(x.size)

def innfeldi(vigur1, vigur2):
    return sum([vigu1[i]*vigur2[i] for i in range(len(vigur1))])

%timeit innfeldi(x, a)

Wall time: 4.78 s

4998161.0032265792

Upvotes: 4

Views: 3714

Answers (2)

James
James

Reputation: 36608

A lot of the functions in numpy are written in optimized C code. However, what you are testing is not a fair comparison.

By iterating over the numpy array, you are asking python to access a single element from the underlying C array, pull it out of C and into python, thereby creating a python object to operate on. There is a good amount of overhead in doing that.

Python will never be as fast C, but a more fair comparison would be to use numpy's built-in array module, along with the optimized functions

import numpy as np
import array
import random
from operator import mul

x = np.random.random(size=10**7)
y = array.array('f', (random.random() for x in range(10**7)))

a = np.ones(x.shape)
b = array.array('d', [1]*10**7)

%%timeit -n3 -r1
np.dot(x,a)
# 3 loops, best of 1: 17.1 ms per loop

%%timeit -n3 -r1
sum(map(mul, y,b))
# 3 loops, best of 1: 777 ms per loop

Upvotes: 4

Paul Panzer
Paul Panzer

Reputation: 53029

Because np.dot executes the actual arithmetic operations and the enclosing loop in compiled code, which is much faster than the Python interpreter.

This principle, grouping repetitive things together and cutting out the interpreter as much as possible is why we can write numerical code in high-level languages such as Python or matlab that runs at acceptable speed.

Upvotes: 6

Related Questions