>백엔드 개발 >Golang >golang의 바이트 정렬 사용에 대한 자세한 설명

golang의 바이트 정렬 사용에 대한 자세한 설명

藏色散人
藏色散人앞으로
2021-09-10 16:42:152404검색

이 글은 go 언어에서 소개한 golang 바이트 정렬 튜토리얼 칼럼입니다. 도움이 필요한 친구들에게 도움이 되길 바랍니다!

최근 성능 최적화 작업을 하고 있는데, 그 중 하나가 상대적으로 큰 공간을 차지하고, 특히 메모리에 있는 숫자가 커서 최적화할 여지가 있는지 궁금합니다. 기억 C 언어의 바이트 정렬을 이해하면 필드 순서를 조정하는 것만으로도 많은 메모리를 절약할 수 있습니다. 이 아이디어는 golang에도 적용됩니다. 그 전에 golang의 크기를 살펴보겠습니다. 의 기본 유형이 차지하는 데이터

So(unsafe.Sizeof(true), ShouldEqual, 1)
So(unsafe.Sizeof(int8(0)), ShouldEqual, 1)
So(unsafe.Sizeof(int16(0)), ShouldEqual, 2)
So(unsafe.Sizeof(int32(0)), ShouldEqual, 4)
So(unsafe.Sizeof(int64(0)), ShouldEqual, 8)
So(unsafe.Sizeof(int(0)), ShouldEqual, 8)
So(unsafe.Sizeof(float32(0)), ShouldEqual, 4)
So(unsafe.Sizeof(float64(0)), ShouldEqual, 8)
So(unsafe.Sizeof(""), ShouldEqual, 16)
So(unsafe.Sizeof("hello world"), ShouldEqual, 16)
So(unsafe.Sizeof([]int{}), ShouldEqual, 24)
So(unsafe.Sizeof([]int{1, 2, 3}), ShouldEqual, 24)
So(unsafe.Sizeof([3]int{1, 2, 3}), ShouldEqual, 24)
So(unsafe.Sizeof(map[string]string{}), ShouldEqual, 8)
So(unsafe.Sizeof(map[string]string{"1": "one", "2": "two"}), ShouldEqual, 8)
So(unsafe.Sizeof(struct{}{}), ShouldEqual, 0)
bool 유형은 1비트만 차지하지만 컴퓨터는 바이트 단위

64 기계이고 int는 8워드를 차지하기 때문에 1바이트도 차지해야 합니다.

string 유형은 16바이트를 차지하며 내부적으로 데이터에 대한 포인터(8바이트)와 int의 길이(8바이트)를 포함합니다.
  • slice 유형은 24바이트를 차지하며 내부적으로 데이터에 대한 포인터를 포함합니다. 포인터(8바이트)와 int의 길이(8바이트)와 int의 용량(8바이트)
  • 맵 유형은 8바이트를 차지하고 맵 구조에 대한 포인터입니다.
  • Can 빈 유형을 나타내려면 struct{}를 사용하세요. 공간을 차지하지 않습니다. 이를 맵의 값으로 사용합니다. 맵을 세트로 사용할 수 있습니다
  • 바이트 정렬
  • 구조체의 필드는 메모리에 촘촘하게 정렬되지 않고 바이트 단위로 정렬됩니다. , int가 8바이트를 차지하면 8의 배수인 주소에만 쓸 수 있습니다. 바이트 정렬이 필요한 이유는 주로 효율성을 고려하기 위한 것이며 더 깊이 인터넷에서 이론을 읽었으며 그다지 신뢰할만하지 않다고 느껴지므로 헛소리는 하지 않겠습니다. 관심이 있으시면 직접 공부해 보세요.
  • // |x---|
    So(unsafe.Sizeof(struct {
        i8 int8
    }{}), ShouldEqual, 1)
  • 이 두 구조의 내용은 정확히 동일합니다. 필드 순서가 조정되어 공간이 33% 절약되었습니다.
// |x---|xxxx|xx--|
So(unsafe.Sizeof(struct {
    i8  int8
    i32 int32
    i16 int16
}{}), ShouldEqual, 12)

// |x-xx|xxxx|
So(unsafe.Sizeof(struct {
    i8  int8
    i16 int16
    i32 int32
}{}), ShouldEqual, 8)

여기서 int64는 8의 배수인 주소에만 나타날 수 있습니다. , 그래서 첫 번째 구조에서 연속된 4바이트가 비어있습니다

// |x---|xxxx|xx--|----|xxxx|xxxx|
So(unsafe.Sizeof(struct {
    i8  int8
    i32 int32
    i16 int16
    i64 int64
}{}), ShouldEqual, 24)

// |x-xx|xxxx|xxxx|xxxx|
So(unsafe.Sizeof(struct {
    i8  int8
    i16 int16
    i32 int32
    i64 int64
}{}), ShouldEqual, 16)

타입 이름을 바꾼 후에도 타입의 크기는 변하지 않았습니다

더 많은 golang 관련 지식은

golang

튜토리얼 칼럼을 방문해 주세요!

위 내용은 golang의 바이트 정렬 사용에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제