Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lambda function internal fields types aren't always inferred correctly #42559

Open
bvdmitri opened this issue Oct 8, 2021 · 3 comments
Open

Comments

@bvdmitri
Copy link
Contributor

bvdmitri commented Oct 8, 2021

Consider two functions:

function foo(::Type{T}) where T
    return (v) -> T(v)
end

function bar(::Type{T}) where T
    R = T
    return (v) -> R(v)
end

while these functions semantically should do the same, their performance is drastically different:

julia> f = foo(Int)
#9 (generic function with 1 method)

julia> b = bar(Int)
#11 (generic function with 1 method)
julia> @btime f(1)
  13.685 ns (0 allocations: 0 bytes)
1

julia> @btime b(1)
  98.902 ns (0 allocations: 0 bytes)
1

This happens because Julia cannot infer correctly the type in the second case, which results in bad performance overall.

julia> dump(f)
#9 (function of type var"#9#10"{Int64})

julia> dump(b)
#11 (function of type var"#11#12"{DataType})
  R: Int64 <: Signed

Provided MWE seems to be very simple, but we hit this performance issue in a very complex code involving a lot of lambda functions. @cscherrer faced similar issue in his MeasureBase.jl package.

julia> versioninfo()
Julia Version 1.6.3
Commit ae8452a9e0 (2021-09-23 17:34 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin19.5.0)
  CPU: Intel(R) Core(TM) i7-7660U CPU @ 2.50GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, skylake)

Reproducible on master 146de38 as well (same hardware).

@KristofferC
Copy link
Member

Dup of notifications #23618?

@bvdmitri
Copy link
Contributor Author

bvdmitri commented Oct 8, 2021

Fixed by #40985 (but not merged). Performance is same after the fix, however inference is still a bit different, not sure if it is a problem:

julia> dump(f)
#1 (function of type var"#1#2"{Int64})

julia> dump(b)
#3 (function of type var"#3#4"{Type{Int64}})
  R: Int64 <: Signed

@JeffBezanson
Copy link
Member

Thanks for reducing this to such a simple example; that saves us a lot of time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants