Say I want to use a np array as a fixed read-only queue and pop off the front of it. This is a natural way to do it:
def pop(k,q):
return q[:k],q[k:]
## example usage:
x = np.arange(1000)
for i in range(5):
a,x = pop(i,x)
print(a)
This seems to be fine, but I want to be sure that there's no hidden state or hidden references that build up if q=q[k:]
gets executed thousands or millions of times. There doesn't seem to be: to take a slice, np simply stores a pointer to the original data buffer, and the new index. But I want to be sure, because if there is something I'm missing, I could represent this as a tuple (np.array,index), which is not as clean:
def pop0(k,q):
x,i = q
return x[i:i+k],(x,i+k)
It will be safe. You can use memory-profiler package to observe memory usage:
For following code:
import numpy as np
@profile
def good_pop():
def pop(k,q):
return q[:k],q[k:]
x = np.arange(10000)
for i in range(5000):
a,x = pop(i,x)
@profile
def bad_pop():
def pop(k,q):
return q[:k].copy(),q[k:].copy()
x = np.arange(10000)
for i in range(5000):
a,x = pop(i,x)
good_pop()
bad_pop()
profiling with command:
$ python3 -m memory_profiler file.py
produced result:
Line # Mem usage Increment Line Contents
================================================
3 49.023 MiB 49.023 MiB @profile
4 def good_pop():
5 49.023 MiB 0.000 MiB def pop(k,q):
6 49.023 MiB 0.000 MiB return q[:k],q[k:]
7 49.023 MiB 0.000 MiB x = np.arange(10000)
8 49.023 MiB 0.000 MiB for i in range(5000):
9 49.023 MiB 0.000 MiB a,x = pop(i,x)
Line # Mem usage Increment Line Contents
================================================
11 49.023 MiB 49.023 MiB @profile
12 def bad_pop():
13 49.234 MiB 0.000 MiB def pop(k,q):
14 49.234 MiB 0.211 MiB return q[:k].copy(),q[k:].copy()
15 49.023 MiB 0.000 MiB x = np.arange(10000)
16 49.234 MiB 0.000 MiB for i in range(5000):
17 49.234 MiB 0.000 MiB a,x = pop(i,x)
A bunch of zeros for good_pop()
is a proof that no extra objects are created in this loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With