Is it good to use counters?

Here are two alternative codes (encoded in Julia) that do pretty much the same thing.

counter = 0
for i = myArray
    counter = counter + 1
    Do1(i)
    Do2(counter)
end

and

for counter = 1:length(myArray)
    i = myArray[counter]
    Do1(i)
    Do2(j)
end

What is good practice? Which code is faster? Which code consumes less memory? Which code is less error prone? Why?

+4
source share
3 answers

In julia you can check this out very easily:

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)

Conclusion:

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)

If you add annotations @inboundsbefore each cycle, you get the following:

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 indexing(A) @code_llvm IR LLVM ( ).

, enumerate - , ( ).

+12

, , () , . Python Julia enumerate:

, (i, x), i - , 1, x - i- . , x, , i .

:

for (j, i) in enumerate(myArray)
    Do1(i)
    Do2(j)
end
+7

(, C) , / ; - /.

(, Julia) , ; , , - /.

For readability / maintainability; the latter seems cleaner to me.

-8
source

Source: https://habr.com/ru/post/1568428/


All Articles