给定一个矩阵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) ]
发布于 2014-02-15 22:11:04
您自己列出的解决方案和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)
,都会为您处理这个问题。
发布于 2019-02-22 06:23:08
从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]
发布于 2015-03-17 00:36:37
根据我的经验,显式迭代比理解快得多。
对列进行迭代也是一个好的建议。
此外,你可以使用新的宏@simd和@inbounds来进一步加速它。
https://stackoverflow.com/questions/21778374
复制相似问题