给定一个矩阵m = [10i+j for i=1:3, j=1:4]
,我可以通过切割矩阵迭代它的行:
for i=1:size(m,1)
print(m[i,:])
end
这是唯一的可能性吗?这是推荐的方式吗?
那么理解呢?切片是否唯一可能迭代矩阵的行?
[ sum(m[i,:]) for i=1:size(m,1) ]
答案 0 :(得分:47)
您自己列出的解决方案以及mapslices
都可以正常工作。但如果通过“推荐”你真正的意思是“高性能”,那么最好的答案是:不要遍历行。
问题在于,由于数组以列主要顺序存储,对于除小矩阵以外的任何其他内容,如果以行主顺序遍历数组,则最终会导致穷cache hit ratio。
正如在excellent blog post中指出的那样,如果你想对行进行求和,最好的办法就是做这样的事情:
msum = zeros(eltype(m), size(m, 1))
for j = 1:size(m,2)
for i = 1:size(m,1)
msum[i] += m[i,j]
end
end
我们以其本机存储顺序遍历m
和msum
,因此每次加载缓存行时,我们都使用所有值,产生的缓存命中率为1.您可能天真地认为它是最好以行主顺序遍历它并将结果累加到tmp
变量,但在任何现代机器上,缓存未命中都比msum[i]
查找要贵得多。
Julia的许多采用region
参数的内部算法(如sum(m, 2)
)会为您处理此问题。
答案 1 :(得分:3)
根据我的经验,显式迭代比理解快得多。
迭代列也是一个很好的建议。
此外,您可以使用新的宏@simd和@inbounds来进一步加速它。
答案 2 :(得分:2)
从Julia 1.1开始,有迭代器实用程序可用于迭代矩阵的列或行。要遍历行:
M = [1 2 3; 4 5 6; 7 8 9]
for row in eachrow(af)
println(row)
end
将输出:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]