min(NaN,5) = NaN (why no @fastmath?)

This is what I get:

julia> @btime findmax_nan($x)
  1.179 ms (0 allocations: 0 bytes)
(3.0f0, 1)

julia> @btime argmax(first, Iterators.filter(!isnan∘first, zip($x, keys($x))))
  3.121 ms (0 allocations: 0 bytes)
(3.0f0, 1)

julia> @btime findmax(skip(isnan, $x))
  3.156 ms (0 allocations: 0 bytes)
(3.0f0, 1)
Julia 1.9.0-beta3
julia> versioninfo()
Julia Version 1.9.0-beta3
Commit 24204a7344 (2023-01-18 07:20 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 20 × 12th Gen Intel(R) Core(TM) i9-12900HK
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-14.0.6 (ORCJIT, alderlake)
  Threads: 20 on 20 virtual cores

I suspect this.

Edit: This seems to be a case where the structure of the problem allows for findmax_nan to be a more optimal solution than using Iterators.filter or skip. For example, if x has less NaN values, then findmax(skip(isnan, x)) runs faster, and in the case where there are no NaNs, it runs nearly as fast (1.45ms here).

Personally I’d rather drop findmax(skip(isnan, x)) into my code than write my own findmax_nan function, unless it was a very hot loop that justified such an optimization, considering that the former pattern is less error-prone and more generally applicable. But the context of the OP (about fastmath) makes this off-topic.

2 Likes