Home > Mobile >  Performance influence of the condition expressions in "for" statement
Performance influence of the condition expressions in "for" statement

Time:10-24

Is there any performance difference between two examples below:

1.

var slice []int{ ... huge list of items... }

for i:=0; i<len(slice); i   { .... do something ....}

2.

var slice []int{ ... huge list of items... }
sliceLen := len(slice)

for i:=0; i<sliceLen; i   { .... do something ....}

Are the condition expressions in "for" statement evaluated at each iteration or only once?

CodePudding user response:

TLDR: There is almost no difference

Good way how to test your problem is benchmarking provided by standard testing library

Create test file eg: forcycle_test.go

package perftest

import (
    "testing"
)

func BenchmarkLenInside(b *testing.B) {
    testData := make([]int, 1000000)

    for i := 0; i < b.N; i   {
        // Benchmarked code start
        for j := 0; j < len(testData); j   {
            doSth(testData[j])
        }
        // end
    }
}

func BenchmarkLenOutside(b *testing.B) {
    testData := make([]int, 1000000)

    for i := 0; i < b.N; i   {
        // Benchmarked code start
        sliceLen := len(testData)
        for j := 0; j < sliceLen; j   {
            doSth(testData[j])
        }
        // end
    }
}

func doSth(n int) {
    _ = n   n
}

Run benchmark

go test -bench .

Example output

goos: linux
goarch: amd64
pkg: forperf
BenchmarkLenInside-6                4543            259117 ns/op
BenchmarkLenOutside-6               4620            258069 ns/op
PASS
ok      forperf 3.811s

The benchmark function must run the target code b.N times. During benchmark execution, b.N is adjusted until the benchmark function lasts long enough to be timed reliably.

As you can see in this benchmark run when you write len function as part of for cycle, it is just slightly slower then version out of cycle.

Type b.N before timed Avg time per b.N iteration
Len in 4543 259117 ns
Len out 4620 258069 ns

Note that several runs gives you different results where len in is A and len out is B

A < B or A ≈ B or even A > B is possible.

CodePudding user response:

Are the condition expressions in "for" statement evaluated at each iteration or only once?

The specification says that the condition is evaluated before each iteration.

Because the value of i changes on each iteration, it makes sense the conditions i<len(slice) and i<sliceLen are evaluated before each iteration.

The compiler can hoist parts of the condition expression evaluation out of the loop as long as the resulting program executes as if the expression is evaluated every time. For example, the compiler can load len(slice) or sliceLen to a register before the loop and use that register in the loop.

Is there any performance difference between two examples below

Both code snippets compare variable i to a value read from a variable. In the first snippet, the value is read from the slice header length field. See Slices: usage and internals if you are not familiar with how a slice is implemented.

The performance should be similar if not identical.

  • Related