인덱스 경계 처리에 대한 3가지 방법의 비교


len 매 루프마다 계속 evaluation하기

따로 length 저장해놓기

range 사용하기


-----


var arr = make([]int, 10000)

func BenchmarkLen(b *testing.B) {
    for i := 0; i < b.N; i++ {
        for j := 0; j < len(arr); j++ {
            _ = j
        }
    }
}

func BenchmarkStoredLen(b *testing.B) {
    for i := 0; i < b.N; i++ {
        length := len(arr)
        for j := 0; j < length; j++ {
            _ = j
        }
    }
}

func BenchmarkRangeIndex(b *testing.B) {
    for i := 0; i < b.N; i++ {
        for j := range arr {
            _ = j
        }
    }
}


-----


BenchmarkLen-4                500000          3967 ns/op
BenchmarkStoredLen-4          500000          3955 ns/op
BenchmarkRangeIndex-4         300000          3916 ns/op


-----


결론 : 속도 때문이라면 암거나 쓰자


참고로 타 언어에서도 length를 따로 저장해두지 않는 쪽이 저장해두는 쪽과 별 차이 없거나 오히려 더 빠른 경우가 꽤 흔한데

컴파일러에서 최적화하기가 전자가 더 쉬워서인 경우도 있고

go처럼 배열-like 객체의 정보를 담은 곳에 length 정보도 따로 저장되어 있어 빠른 참조가 가능해서인 경우도 있고..


암튼 최적화한답시고 따로 저장해둘 필요는 없다