使用计数器是好的做法吗?

Rem*_*i.b 4 algorithm performance counter for-loop julia

这里有两个替代代码(在Julia中编码),它们基本上是相同的.

counter = 0
for i = myArray
    counter = counter + 1
    Do1(i)
    Do2(counter)
end
Run Code Online (Sandbox Code Playgroud)

for counter = 1:length(myArray)
    i = myArray[counter]
    Do1(i)
    Do2(j)
end
Run Code Online (Sandbox Code Playgroud)

什么是好的做法?哪个代码更快?哪个代码消耗的内存较少?哪个代码不易出错?为什么?

tho*_*oly 12

在julia中,您可以非常轻松地测试它:

function indexing(A)
    si = 0
    sA = zero(eltype(A))
    for i = 1:length(A)
        sA += A[i]
        si += i
    end
    si, sA
end

function counter(A)
    si = 0
    sA = zero(eltype(A))
    i = 0
    for a in A
        sA += a
        si += (i += 1)
    end
    si, sA
end

function enumrt(A)
    si = 0
    sA = zero(eltype(A))
    for (i, a) in enumerate(A)
        sA += a
        si += i
    end
    si, sA
end

A = rand(Float32, 10^8)
# Compile all the functions, including those needed to time things
indexing(A)
counter(A)
enumrt(A)
@time 1+1

# Test the timing
@time indexing(A)
@time counter(A)
@time enumrt(A)
Run Code Online (Sandbox Code Playgroud)

输出:

elapsed time: 4.61e-6 seconds (80 bytes allocated)
elapsed time: 0.12948093 seconds (144 bytes allocated)
elapsed time: 0.191082557 seconds (144 bytes allocated)
elapsed time: 0.331076493 seconds (160 bytes allocated)
Run Code Online (Sandbox Code Playgroud)

如果你@inbounds在每个循环之前添加注释,那么你得到这个:

elapsed time: 4.632e-6 seconds (80 bytes allocated)
elapsed time: 0.12512546 seconds (144 bytes allocated)
elapsed time: 0.12340103 seconds (144 bytes allocated)
elapsed time: 0.323285599 seconds (160 bytes allocated)
Run Code Online (Sandbox Code Playgroud)

所以前两个之间的区别实际上只是自动边界检查删除的有效性.最后,如果您真的想深入了解详细信息,可以使用@code_native indexing(A)@code_llvm检查LLVM IR(内部表示)来检查生成的机器代码.

但是,在某些情况下,可读性可能更重要,因此该enumerate方法是我经常使用的方法(但不是真正的性能关键代码).


Ruf*_*ind 7

我实际上并不太了解朱莉娅,但这种模式很常见,大多数(理智)语言都有内置函数来帮助你处理这种犹豫不决.在Python和Julia中,它被称为enumerate:

返回其产生一个迭代(i, x),其中i是从1开始的指标,x是从给定的迭代的第i个值.当您不仅需要x迭代的值,而且还需要迭代的索引时i,它非常有用.

对于您的示例,它看起来像:

for (j, i) in enumerate(myArray)
    Do1(i)
    Do2(j)
end
Run Code Online (Sandbox Code Playgroud)