Reputation: 185
I am writing code and efficiency is very important. Actually I need 2d array, that I am filling with 0 and 1 in for loop. What is better and why?
Make empty array and fill it with "0" and "1". It's pseudocode, my array will be much bigger.
Make array filled by zeros and make if() and if not zero - put one.
So I need information what is more efficiency: 1. Put every element "0" and "1" to empty array or 2. Make if() (efficiency of 'if') and then put only "1" element.
Upvotes: 2
Views: 7621
Reputation: 75
In most cases, there is no significant performance difference between np.empty()
and np.zeros()
However, np.zeros()
may be slightly slower due to the additional step of initializing the allocated memory to zero: 2 * O(n)
Upvotes: 0
Reputation: 734
It is better to create array of zeros and fill it using if-else. Even conditions makes slow your code, reshaping empty array or concatenating it with new vectors each iteration of loop is more slower operation, because each time new array of new size is created and old array is copied there together with new vector value by value.
Upvotes: 1
Reputation: 11591
I would go with zeros(). The performance bottleneck will be your python for loop anyway.
Fortunately, Numpy now as a JIT compiler, which can turn your crummy and slow python for loop into machine code:
I tried it. It's a bit rough around the edges, but the speedups can be quite spectacular compared to bare python code. Of course the best choice is to vectorize using numpy, but you don't always have a choice.
Upvotes: 2
Reputation: 231738
Ae = np.empty(10000)
A0 = np.zeros((10000)
differ slightly in how memory is initially allocated. But any differences in time will be minor if you go on and do something like
for i in range(10000):
Ae[i] = <some calc>
or
for i in range(10000):
val = <some calc>
if val>0:
A0[i] = val
If I had to loop like this, I'd go ahead and use np.zeros
, and also use the unconditional assignment. It keeps the code simpler, and compared to everything else that is going on, the time differences will be minor.
Sample times:
In [33]: def foo0(N):
...: A = np.empty(N,int)
...: for i in range(N):
...: A[i] = np.random.randint(0,2)
...: return A
...:
In [34]: def foo1(N):
...: A = np.zeros(N,int)
...: for i in range(N):
...: val = np.random.randint(0,2)
...: if val:
...: A[i] = val
...: return A
...:
3 ways of assigning 10 0/1 values
In [35]: foo0(10)
Out[35]: array([0, 0, 1, 0, 0, 1, 0, 1, 1, 0])
In [36]: foo1(10)
Out[36]: array([0, 1, 1, 1, 1, 1, 1, 1, 0, 0])
In [37]: np.random.randint(0,2,10)
Out[37]: array([0, 1, 1, 0, 1, 1, 1, 0, 0, 1])
times:
In [38]: timeit foo0(1000)
100 loops, best of 3: 4.06 ms per loop
In [39]: timeit foo1(1000)
100 loops, best of 3: 3.95 ms per loop
In [40]: timeit np.random.randint(0,2,1000)
... cached.
100000 loops, best of 3: 13.6 µs per loop
The 2 loop times are nearly the same.
Upvotes: 1