我使用数组解析来定义自定义类型数组元素的感兴趣值。
sum([value.interest for value in ArrayofMyType if condition])
此表达式本身处于迭代循环中。这意味着每个周期,这种理解都使用新的记忆。此外,每次条件可能会对结果数组施加不同的长度,并且在循环外定义具有固定长度的预定义数组可能不是最好的方法。
每次循环运行时都会产生开销,我不知道如何提高效率并更好地利用内存。有没有人可以用这个指导我?理解在风格上很方便,但我认为在我的案例中并不是最有效的。
代码风格是:
for i in 1:MAX_ITER
### Some code above
sum([value.interest for value in ArrayofMyType if condition])
### Some code below
end
答案 0 :(得分:7)
您可以使用生成器表达式(只省略括号):
sum(value.interest for value in ArrayofMyType if condition)
这不会创建中间数组,而是创建类型Generator
的实例。你可以做到
g = (value.interest for value in ArrayofMyType if condition)
在函数调用之外创建这样的对象。它实现了迭代器接口,特别是方法start
,next
,done
以及一些其他方法,如length
,因此可以在接受迭代器的任何地方使用它。
如果所有内容都是类型稳定,则与手写循环相比的开销几乎是恒定的,对于较大的数组而言可忽略不计。否则,开销可能很大。
对于短数组,开销仍然很大,手写循环可能是更好的解决方案:
immutable A{T} x::T end
const a = [A(i) for i in 1:100]
mysum(a) = mysum(eltype(a), a)
function mysum{T}(::Type{A{T}}, a)
sum = zero(T)
@inbounds for i in eachindex(a)
sum += a[i].x
end
return sum
end
using BenchmarkTools
@benchmark sum(e.x for e in $a)
@benchmark mysum($a)
这会在我的电脑上提供50ns
vs 15ns
。