On Tue, Jan 18, 2022, at 21:55, Warren Weckesser wrote:
> expr = 'z.real**2 + z.imag**2'
>
> z = generate_sample(n, rng)
🤔 If I duplicate the `z = ...` line, I get the fast result throughout. If, however, I use `generate_sample(1, rng)` (or any other value than `n`), it does not improve matters.
Could this be a memory caching issue?
I can also reproduce that, but only on my Linux boxes. My MacMini does not notice the difference.
Interestingly enough, you don't even need an additional call to `generate_sample(n, rng)`. If one use `z = np.empty(...)` and then do an assignment, like:
z = np.empty(n, dtype=np.complex128)
z[:] = generate_sample(n, rng)
then everything runs at the same speed:
numpy version 1.20.3
 142.3667 microseconds
 142.3717 microseconds
 142.3781 microseconds
 142.7593 microseconds
 142.3579 microseconds
 142.3231 microseconds
As another data point, by doing the same operation but using numexpr I am not seeing any difference either, not even on Linux:
numpy version 1.20.3
numexpr version 2.8.1
 95.6513 microseconds
 88.1804 microseconds
 97.1322 microseconds
 105.0833 microseconds
 100.5555 microseconds
 100.5654 microseconds
[it is rather like a bit the other way around, the second iteration seems a hair faster]
See the numexpr script below.
I am totally puzzled here.
"""
import timeit
import numpy as np
import numexpr as ne
def generate_sample(n, rng):
  return rng.normal(scale=1000, size=2*n).view(np.complex128)
print(f'numpy version {np.__version__}')
print(f'numexpr version {ne.__version__}')
print()
rng = np.random.default_rng()
n = 250000
timeit_reps = 10000
expr = 'ne.evaluate("zreal**2 + zimag**2")'
z = generate_sample(n, rng)
zreal = z.real
zimag = z.imag
for _ in range(3):
  t = timeit.timeit(expr, globals=globals(), number=timeit_reps)
  print(f"{1e6*t/timeit_reps:9.4f} microseconds")
print()
z = generate_sample(n, rng)
zreal = z.real
zimag = z.imag
for _ in range(3):
  t = timeit.timeit(expr, globals=globals(), number=timeit_reps)
  print(f"{1e6*t/timeit_reps:9.4f} microseconds")
print()
"""
--