【发布时间】:2020-05-25 05:38:54
【问题描述】:
在这里完成 Julia 新手。
给定一个数组数组,我想组合每个子数组的对应元素。像这样的:
[2, 7, 9] [2, 3, 2, 7, 3]
[3, 5, 4] [7, 5, 7, 9, 5]
[2, 7, 7] -> [9, 4, 7, 1, 1]
[7, 9, 1]
[3, 5, 1]
搜索 stackoverflow 我遇到了几个解决方案,而不是直接循环或列表理解。
julia> a=Vector{Int}[rand(1:10,3) for i=1:5]
5-element Array{Array{Int64,1},1}:
[2, 7, 9]
[3, 5, 4]
[2, 7, 7]
[7, 9, 1]
[3, 5, 1]
julia> using BenchmarkTools
julia> @btime a2=mapslices( x -> [x], hcat(a...), dims=2)[:]
6.174 μs (65 allocations: 3.45 KiB)
3-element Array{Array{Int64,1},1}:
[2, 3, 2, 7, 3]
[7, 5, 7, 9, 5]
[9, 4, 7, 1, 1]
julia> @btime a3=[getindex.(a,i) for i=1:length(a[1])]
948.087 ns (14 allocations: 768 bytes)
3-element Array{Array{Int64,1},1}:
[2, 3, 2, 7, 3]
[7, 5, 7, 9, 5]
[9, 4, 7, 1, 1]
我的问题是:为什么第二个比第一个快六倍?和hcat有关系吗?
【问题讨论】:
-
如果您想要第三个更好的,请使用:
julia> @btime a3 = [[a[i] for a in $a] for i = 1:3] 193.593 ns (9 allocations: 640 bytes) 3-element Array{Array{Int64,1},1}: [2, 3, 2, 7, 3] [7, 5, 7, 9, 5] [9, 4, 7, 1, 1]。这一切都归结为分配,第一个例子(65 allocations: 3.45 KiB),第二个(14 allocations: 768 bytes),还有我的(9 allocations: 640 bytes)。在 Julia 代码中,最好避免任何不必要的分配以获得最大速度。 -
不,这只是一个基准测试人工制品。您将
a插入到基准表达式中,而@toylas 没有。如果插值正确,它们具有相似的性能。不过,我更愿意建议:[getindex.(a,i) for i in eachindex(first(a))],在我的笔记本电脑上,它的速度提高了 10%,但更重要的是,它更强大(尽管你仍然应该这样做)。顺便说一句,我认为写[a[i] for a in a]不是一个好主意,将a重用作为迭代变量非常令人困惑,事实上我有点惊讶它甚至可以工作。 -
注意原始时序问题,在非常量全局变量上进行基准测试是一个问题。您应该通过编写
$a而不是a来插入它们,就像@aboammar 一样,或者将其设为常量。我已经看到这会导致误导性的结果,甚至可以颠倒正在考虑的不同替代方案的顺序,因为由此产生的类型推断中断占主导地位。我没有检查这是否是这样一种情况