On Wed, Jan 19, 2022 at 11:50 AM Francesc Alted <faltet@gmail.com> wrote:


On Wed, Jan 19, 2022 at 7:33 AM Stefan van der Walt <stefanv@berkeley.edu> wrote:
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:

Just turning the view into a copy inside `generate_sample()` will also make the difference go away, for probably the same reason as this version.

András


 

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()
"""

--
Francesc Alted
_______________________________________________
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-leave@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: deak.andris@gmail.com