Hello!
While trying out some things in the julia REPL to see how a[i…] = x is transformed into setindex!(a, x, i…). I came across multiple questions :
I am wondering why the prototype of setindex! is setindex!(A::AbstractArray,X::Any,inds::Vargarg{Any})
and not setindex!(A::AbstractArray,X::Any,inds:Tuple{Vararg{Any})
I thought it was for performance reasons but when i tried to replicate the behavior and benchmark it with BenchmarkTools.jl, the results were not exactly what i expected.
If I declare those two lambda functions:
f = (a, b::Vararg) -> b
g = (a, b::Tuple{Vararg}) -> b
And benchmark (with 100 000 samples) f(1, 2)
and g(1, (2,))
then effectively f
is a little faster than g
by approx 0.5 nano-seconds in median time.
BUT if i re-run this benchmark with f(1, 2, 3)
and g(1, (2, 3))
then f
is terribly slower that g
. Where g
takes 15 ns in median time, f
takes 171 ns ??
1: First question: is this performance gap normal ? Is the first proto for setindex! preferred over the second because setindex! is practically never called with multiple indices?
Moreover, It seems like there isn’t a way to define easily a Tuple{Vararg} and extract its content via the argument destructuring syntax.
I can do
f = (a, b) -> b
and
f = (a, b...) -> b
and
g = (a, (b,)) -> b
but not
g = (a, (b...,)) -> b
2: Am I missing something syntactically speaking ?
Anyway, sorry for the long post… here is my versioninfo() in case. Thanks!
julia> versioninfo()
Julia Version 1.3.1
Commit 2d5741174c (2019-12-30 21:36 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Core™ i7-8750H CPU @ 2.20GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.1 (ORCJIT, skylake)