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

Avoid constructing an array only to splat it to make a tuple in tuple_tfunc #36926

Merged
merged 2 commits into from
Aug 12, 2020

Conversation

oxinabox
Copy link
Contributor

@oxinabox oxinabox commented Aug 5, 2020

No description provided.

base/compiler/tfuncs.jl Outdated Show resolved Hide resolved
@vtjnash
Copy link
Member

vtjnash commented Aug 5, 2020

Those both still construct it (can't avoid that as it's needed for dispatch), they would just also make a closure and allocate some other objects too.

@oxinabox
Copy link
Contributor Author

oxinabox commented Aug 5, 2020

I made a similar case to time in the REPL, not sure that it is completely valid, but it seems like it is much faster to use ntuple.

julia> foo_vecsplat(x) = tuple(Any[x[i] for i in 1:length(x)]...)
foo_vecsplat (generic function with 1 method)

julia> foo_ntuple(x) = ntuple(i->x[i], length(x))
foo_ntuple (generic function with 1 method)

julia> foo_generator(x) = Tuple(x[i] for i in 1:length(x))
foo_generated (generic function with 1 method)

julia> @btime foo_vecsplat([1,2,3,4,5,6,7,8]);
  244.023 ns (3 allocations: 368 bytes)

julia> @btime foo_ntuple([1,2,3,4,5,6,7,8]);
  32.596 ns (2 allocations: 224 bytes)

julia> @btime foo_generator([1,2,3,4,5,6,7,8]);
  286.795 ns (3 allocations: 368 bytes)

It seems like it still holds with @nospecialize

julia> bar_ntuple(@nospecialize x) = ntuple(i->x[i], length(x))
bar_ntuple (generic function with 1 method)

julia> @btime bar_ntuple([1,2,3,4,5,6,7,8]);
  32.676 ns (2 allocations: 224 bytes)

@vtjnash
Copy link
Member

vtjnash commented Aug 6, 2020

That's not quite valid. Using ntuple is a bit faster, but not by quite that much (it's the same implementation as vecsplat, but additionally has optimizations for less than 10 elements):

julia> @btime foo_ntuple($(Any[1,2,3,4,5,6,7,8]));
  157.234 ns (1 allocation: 80 bytes)
julia> @btime foo_vecsplat($(Any[1,2,3,4,5,6,7,8]));
  304.480 ns (2 allocations: 224 bytes)

@oxinabox
Copy link
Contributor Author

oxinabox commented Aug 6, 2020

... but additionally has optimizations for less than 10 elements ...

Are those optimisations relevent here?
Trying to familarise myself more with this code

@JeffBezanson
Copy link
Member

Tuples are usually small, so that's the case we're likely to hit here. But, this code probably does not run often enough in the compiler to have an impact.

Copy link
Member

@vtjnash vtjnash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. But since you've done the work to identify it, seems sensible to merge.

@Keno Keno merged commit fedde78 into JuliaLang:master Aug 12, 2020
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

Successfully merging this pull request may close these issues.

4 participants