-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Set @nospecialize
for something
#46115
base: master
Are you sure you want to change the base?
Conversation
The test failures appear unrelated. |
something(x::Nothing, y...) = something(y...) | ||
something(x::Some, y...) = x.value | ||
something(x::Any, y...) = x | ||
something(x::Nothing, @nospecialize(y...)) = something(y...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one seems to be sketchy, as specialization may produce better code for the y...
part. We should double check the performance for splat cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well spotted. The nospecialize version appears to be slightly slower on both Julia 1.8-rc3 and 1.9.0 (5e081d6). I cannot spot a difference in the @code_warntype
though which I don't understand.
julia> _c(x::Nothing, @nospecialize(y...)) = something(y...)
_c (generic function with 1 method)
julia> _d(x::Nothing, y...) = something(y...)
_d (generic function with 1 method)
julia> @btime _c(Tuple([nothing; rand([1, 2, nothing], 100)])...);
96.258 μs (9 allocations: 3.50 KiB)
julia> @btime _d(Tuple([nothing; rand([1, 2, nothing], 100)])...);
93.493 μs (9 allocations: 3.50 KiB)
julia> @btime _c(Tuple([nothing; rand([1, 2, nothing], 100)])...);
95.241 μs (9 allocations: 3.50 KiB)
julia> @btime _d(Tuple([nothing; rand([1, 2, nothing], 100)])...);
94.229 μs (9 allocations: 3.55 KiB)
Even more strange, the nospecialize version for something(x::Any, y...) = x
is slower than the original version too?
julia> _a(@nospecialize(x::Any), @nospecialize(y...)) = x
_a (generic function with 1 method)
julia> _b(x::Any, y...) = x
_b (generic function with 1 method)
julia> @btime _b(Tuple([1; rand([1, 2, nothing], 100)])...);
61.069 μs (6 allocations: 3.45 KiB)
julia> @btime _a(Tuple([1; rand([1, 2, nothing], 100)])...);
62.778 μs (6 allocations: 3.45 KiB)
julia> @btime _b(Tuple([1; rand([1, 2, nothing], 100)])...);
61.295 μs (6 allocations: 3.41 KiB)
julia> @btime _a(Tuple([1; rand([1, 2, nothing], 100)])...);
63.034 μs (6 allocations: 3.41 KiB)
I don't get it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You way first understand what @nospecialize
really does. Read #41931 if interested.
This reduces the time to first
something
and shouldn't have a negative effect on performance. Benchmarked with Julia 1.8-rc3:The benchmark shows that
_something
has no compilation time for arbitrary tuples after the first invocation. The original methodsomething
does have compilation time. Furthermore, the running time does not seem to be affected and I cannot think of a reason where it would sincef(@nospecialize(x)) = x
correctly infers the return type even with the@nospecialize
annotation.