2017-01-12 1 views
1

더 빠른 것을 찾고 싶었습니다 : struct vs array. 그래서 구조체의 멤버에게 4 개의 int 값 (1,2,3, 4)을 쓰고 길이 4의 배열로 쓰는 GO 코드를 작성했습니다. 작성하는 데 걸리는 시간을 찾으려고 노력했습니다.코드와 성능의 순서

사례 1 : 먼저 구조에 값을 쓰고 배열에 값을 씁니다. 여기서 배열은 구조보다 빠르다는 것을 알았습니다.

package main 

import (
    "fmt" 
    "time" 
) 

type abc struct { 
    a, b, c, d int 
} 

func main() { 

    var obj abc 

    t1 := time.Now() 
    obj.a = 1 
    obj.b = 2 
    obj.c = 3 
    obj.d = 4 
    t2 := time.Since(t1) 

    fmt.Println("Struct access time: : ", t2) 

    a := make([]int, 4) 
    t3 := time.Now() 
    a[0] = 1 
    a[1] = 2 
    a[2] = 3 
    a[3] = 4 
    t4 := time.Since(t3) 

    fmt.Println("Array access time: : ", t4) 

} 

사례 2 : 두 번째로 배열에 값을 쓰고 구조체에 값을 씁니다. 여기 구조가 배열보다 빠르다는 것이 발견되었습니다.

package main 

import (
    "fmt" 
    "time" 
) 

type abc struct { 
    a, b, c, d int 
} 

func main() { 

    var obj abc 

    a := make([]int, 4) 
    t3 := time.Now() 
    a[0] = 1 
    a[1] = 2 
    a[2] = 3 
    a[3] = 4 
    t4 := time.Since(t3) 

    fmt.Println("Array access time: : ", t4) 

    t1 := time.Now() 
    obj.a = 1 
    obj.b = 2 
    obj.c = 3 
    obj.d = 4 
    t2 := time.Since(t1) 

    fmt.Println("Struct access time: : ", t2) 

} 

성능이 내가 처음 작성한 것에 따라 달라지는 이유는 무엇입니까? 내가 처음에 쓰는 것은 느린 것 같습니다. 왜 그래야만하지?

답변

1

다른 답변은 타이밍 차이를 설명하고 struct 대 슬라이스로 들어가 보겠습니다.

컴파일러가 슬라이스가 충분히 크다는 것을 컴파일 시간에 파악할 수있는 경우 슬라이스 및 구조체의 요소에 액세스하면 동일한 코드가 생성됩니다. 물론 현실에서는 컴파일러가 슬라이스의 크기를 알 수 없으며 구조체 또는 슬라이스로 작업하는 경우 완전히 다른 최적화가 적용되므로 성능을 측정하려면 전체를 살펴야합니다 프로그램 및 그 행동, 하나의 특정 작업을합니다.

9

처음으로 코드를 실행하면 약간의 (상당한) 오버 헤드가 발생할 수 있습니다. (예 : 내부 버퍼)가 필요할 때까지 지연 될 수 있습니다. 똑같은 것을 다시 실행하면 시간이 훨씬 더 걸릴 수 있습니다. 차이는 심지어 의 몇 배인 일 수 있습니다.

실행 시간을 측정하려면 여러 번 실행하고 여러 실행의 실행 시간을 측정하고 평균 시간을 계산해야합니다. 위에서 언급 한 이유로 계산에서 첫 번째 (일부) 실행을 제외하는 것도 좋은 생각입니다.

Go에서는 테스트 파일과 벤치 마크 기능을 사용하는 것이 가장 쉽고 쉽습니다. 자세한 내용과 예제는 testing 패키지 문서를 읽으십시오.

귀하의 경우

이 같은 벤치마킹 할 수 있습니다 그것을 저장

package main 

import "testing" 

type abc struct { 
    a, b, c, d int 
} 

func BenchmarkSlice(b *testing.B) { 
    a := make([]int, 4) 
    for i := 0; i < b.N; i++ { 
     a[0] = 1 
     a[1] = 2 
     a[2] = 3 
     a[3] = 4 
    } 
} 

func BenchmarkStruct(b *testing.B) { 
    a := abc{} 
    for i := 0; i < b.N; i++ { 
     a.a = 1 
     a.b = 2 
     a.c = 3 
     a.d = 4 
    } 
} 

을 파일로 something_test.go처럼 go test -bench .으로 실행합니다. 출력 :

BenchmarkSlice-4  2000000000   1.24 ns/op 
BenchmarkStruct-4  2000000000   0.31 ns/op 

당신은 구조체를 사용하여 약 4 배 빠르다는 것을 알 수있다. 벤치 마크 기능의 순서를 바꾸면 비슷한 결과를 얻을 수 있습니다.

+0

벤치 테스트에서'struct'는'slice'보다 빠릅니다. 결론적으로, 당신은 그 반대를 썼습니다. – Motakjuq

+0

@ 모 타크 주크 그래, 그것은 오타 였고, 이미 고쳤다. – icza

+0

@icza 나는 당신이 말한 것을 이해합니다. 나는 두 코드가 동일하게 동작 할 것을 기대했다. 모든 명령어 (배열과 구조체 모두)가 STR

과 같지 않을 것입니다. 따라서 양쪽 모두 동등한 실행 시간을 가져야합니다. – Jsmith

관련 문제