这里有两个替代代码(在Julia中编码),它们基本上是相同的. counter = 0for i = myArray counter = counter + 1 Do1(i) Do2(counter)end 和 for counter = 1:length(myArray) i = myArray[counter] Do1(i) Do2(j)end 什么是好的做法
counter = 0 for i = myArray counter = counter + 1 Do1(i) Do2(counter) end
和
for counter = 1:length(myArray) i = myArray[counter] Do1(i) Do2(j) end
什么是好的做法?哪个代码更快?哪个代码消耗的内存较少?哪个代码不易出错?为什么?
在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)
输出:
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)
如果你在每个循环之前添加@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)
所以前两个之间的区别实际上只是自动边界检查删除的有效性.最后,如果您真的想深入了解详细信息,可以使用@code_native索引(A)检查生成的机器代码,或使用@code_llvm检查LLVM IR(内部表示).
但是,在某些情况下,可读性可能更重要,因此枚举方法是我经常使用的方法(但不是真正的性能关键代码).