import ( "코딩", "행복", "즐거움" )

Go 필드 정렬해서 메모리 절약하기 본문

GO

Go 필드 정렬해서 메모리 절약하기

더코드마니아 2022. 10. 3. 16:49

원문참조:

https://medium.com/@didi12468/golang-field-alignment-2e657e87668a

 

Golang Field Alignment

Golang defines the concept of byte alignment in the structure struct (appropriate adjustment of the field order can save a lot of memory)

medium.com

 

Golang은 구조체에서 바이트 정렬의 개념을 가지고 있어 

필드 순서에 따라 메모리 사이즈가 달라질 수 있다. 

필드 순서에 주의하면 메모리 절약을 할 수 있다는 말이다. 

 

설명을 이어가기에 앞서, 

golang의 자료형의 사이즈에 대해 정리한다. 

 

자료형 사이즈
bool 1 byte
byte 1 byte
int  32bit ==> 4 byte ( int32 )
64bit ==> 8 byte ( int64 ) 
int32 4 byte
int64 8 byte
float32 4 byte
float64 8 byte
string 16 byte
[] 24 byte
map 8 byte

아래 예제는 64 bit 환경이라고 가정 한다. 

아래 코드는 MyData라는 구조체가 어떠한 메모리 구조로 구성이 되는지 알아보는 실험 코드이다. 

type MyData struct {
	f0 byte
	f1 int
	f2 float32
	f3 string
	f4 []int
	f5 map[string]string
}
 
func main() {
	typ := reflect.TypeOf(MyData{})
	fmt.Printf("Struct is %d bytes long\n", typ.Size())
	// We can run through the fields in the structure in order
	n := typ.NumField()
	for i := 0; i < n; i++ {
		field := typ.Field(i)
		fmt.Printf("%s at offset %v, size=%d, align=%d\n",
			field.Name, field.Offset, field.Type.Size(),
			field.Type.Align())
	}
}

 

결과를 보기 좋게 표로 그려보았다. 

녹색은 사용하는 메모리 공간이고, 회색은 낭비되는 공간이다. 

64bit 시스템에서는 한번에 8바이트의 데이터만 가져올 수 있기 때문에 

아래 결과는 8byte * 9 = 총 72 byte의 결과가 출력 되었다. 

 

결과값: 

Output:
Struct is 72 bytes long
f0 at offset 0, size=1, align=1
f1 at offset 8, size=8, align=8
f2 at offset 16, size=4, align=4
f3 at offset 24, size=16, align=8
f4 at offset 40, size=24, align=8
f5 at offset 64, size=8, align=8

다음 예제에서 구조체의 byte 수를 예측 해 보라 

 

1번 예제 .. 몇 바이트일까 ? 

type MyData struct {
	f0 byte
	f1 int
	f2 byte
	f3 int
	f4 byte
	f5 int
}

2번 예제 ... 몇 바이트 일까 ? 

type MyData struct {
	f0 byte
	f2 byte
	f4 byte
	f1 int
	f3 int
	f5 int
}

 

 

답은 스크롤을 내리면 나온다. 

충분히 생각해보고 스크롤을 내려보자

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

 

1번 답  ==> 48 byte 

type MyData struct {
	f0 byte
	f1 int
	f2 byte
	f3 int
	f4 byte
	f5 int
}

Output:
Struct is 48 bytes long
f0 at offset 0, size=1, align=1
f1 at offset 8, size=8, align=8
f2 at offset 16, size=1, align=1
f3 at offset 24, size=8, align=8
f4 at offset 32, size=1, align=1
f5 at offset 40, size=8, align=8

 

 

 

2번 답 ==> 32 byte 

type MyData struct {
	f0 byte
	f2 byte
	f4 byte
	f1 int
	f3 int
	f5 int
}

Output:
Struct is 32 bytes long
f0 at offset 0, size=1, align=1
f2 at offset 1, size=1, align=1
f4 at offset 2, size=1, align=1
f1 at offset 8, size=8, align=8
f3 at offset 16, size=8, align=8
f5 at offset 24, size=8, align=8

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'GO' 카테고리의 다른 글

GO 백엔드 개발자 학습 로드맵  (0) 2022.11.16
GO 디자인 패턴에 관심이 있다면 ??  (0) 2022.11.16
Golang 벤치마킹 함수 성능 개선  (0) 2022.11.15
pprof  (0) 2022.10.05
메모리 절약 패키지, fieldalignment 사용  (0) 2022.10.03