Literally the only reason the compiler was able to fold your computation was because the input to your Fix
thing was part of the benchmarking expression. Here, let me help you out:
julia> @benchmark Fix{(1,2,-3,-1)}(f, vals, z=5)(args...; kw...) setup=(f=(args...;kwargs...)->(args...,(;kwargs...));vals=(:a,:b,:getting_close,:END); args=(:y, 1, 2); kw=(:k=>2,))
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
Range (min … max): 52.667 μs … 176.066 μs ┊ GC (min … max): 0.00% … 0.00%
Time (median): 53.412 μs ┊ GC (median): 0.00%
Time (mean ± σ): 55.087 μs ± 5.945 μs ┊ GC (mean ± σ): 0.00% ± 0.00%
▆█▅▂▁ ▃ ▁
█████▆▅█▆▆▇▆▄▅█▆▅▆▆▄▄██▇▅▅▇▆▆▇▆▅▅▆▅▅▆▅▅▅▄▄▄▄▄▂▄▄▄▄▄▅▂▃▄▄▅▅▅▆ █
52.7 μs Histogram: log(frequency) by time 84.9 μs <
Memory estimate: 2.59 KiB, allocs estimate: 45.
julia> @btime Fix{(1,2,-3,-1)}(f, vals, z=5)(args...; kw...) setup=(f=(args...;kwargs...)->(args...,(;kwargs...));vals=(:a,:b,:getting_close,:END); args=(:y, 1, 2); kw=(:k=>2,))
52.683 μs (45 allocations: 2.59 KiB)
(:a, :b, :y, 1, :getting_close, 2, :END, (k = 2, z = 5))
And ok, you might argue “but the function is fixed!”, then here, have this benchmark where only the input is not known and thus can’t be folded:
julia> @benchmark Fix{(1,2,-3,-1)}((args...;kwargs...)->(args...,(;kwargs...)), (:a,:b,:getting_close,:END), z=5)(args...; kw...) setup=(args=(:y, 1, 2); kw=(:k=>2,))
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
Range (min … max): 51.705 μs … 203.229 μs ┊ GC (min … max): 0.00% … 0.00%
Time (median): 52.434 μs ┊ GC (median): 0.00%
Time (mean ± σ): 54.838 μs ± 7.742 μs ┊ GC (mean ± σ): 0.00% ± 0.00%
██▄▂ ▁ ▁ ▂▂ ▁ ▂
███████▇▇█▁▇█▆▆█▅▅██▇▆█████▇▇██▇▇▇▇▇▆▆▆▇▆▇▆▆▆▆▅▆▆▆▇▇▆▆▅▆▆▆▄▅ █
51.7 μs Histogram: log(frequency) by time 89 μs <
Memory estimate: 2.55 KiB, allocs estimate: 44.
julia> @btime Fix{(1,2,-3,-1)}((args...;kwargs...)->(args...,(;kwargs...)), (:a,:b,:getting_close,:END), z=5)(args...; kw...) setup=(args=(:y, 1, 2); kw=(:k=>2,))
51.934 μs (44 allocations: 2.55 KiB)
(:a, :b, :y, 1, :getting_close, 2, :END, (k = 2, z = 5))
It’s not better. The only case where it could be better is if everything is tuple, always, which is just not a realistic use case.
To me your reply just shows that you’re ignorant about what you’re actually defining and how that actually works. This is not convincing.