`Tuple{Varag{Real}}`与`Vector{Real}`的存储效率对比?

两个功能类似的数据结构

struct Foo
    val::Tuple{Vararg{Real}}
end

struct Bar
    val::Vector{Real}
end

发现实例化一个FooBar更快?!

julia> @time bar = Bar([1,2,4])
  0.000004 seconds (3 allocations: 176 bytes)
Bar(Real[1, 2, 4])

julia> @time bar = Bar([1,2,4])
  0.000006 seconds (3 allocations: 176 bytes)
Bar(Real[1, 2, 4])

julia> @time foo = Foo((1,2,3))
  0.000001 seconds
Foo((1, 2, 3))

julia> @time foo = Foo((1,2,3))
  0.000001 seconds
Foo((1, 2, 3))

是否意味着某些情况下Tuple拥有着更好的存储效率?

是。

但 Tuple 弄长了,估计性能还是会有问题。

可以做个长度作为变量的 benchmark

嗯,可能元素少于100个还是不错的,就如 StaticArrays

需要注意的是, isconcretetype(Tuple{Vararg{Real}}) = false。虽然你的类型标注是Tuple{Vararg{Real}},但实际构造foo时,foo.val 是以“boxed”的NTuple{3,Int} 形式存在的。
相比之下,isconcretetype(Vector{Real}) = true, 也即bar.val是一个“unboxed”的Vector{Real}(其内部每一个元素都是一个“boxed object”)
从这个角度来说foo的存储效率确实比bar高。(详见dev doc
但这不意味着foo在后续调用中具有更好的效率

julia> @btime $foo.val[$1]
  17.034 ns (0 allocations: 0 bytes)
1

julia> @btime $bar.val[$1]
  2.300 ns (0 allocations: 0 bytes)
1
3 个赞

确实,已经用回了Vector,不过是Vector{Any},省了类型检查 :grinning: