+2

Golang memory các loại type.

Hiện tại hầu hết lập trình viên golang thường sẽ ít quan tâm đến việc sử dụng memory của nó, ai cũng cho rằng golang rất tốt cho việc tối ưu tài nguyên, nhưng khi bạn thực sự quan tâm thì đó là một sự lãng phí.


  • Khi ứng dụng được chạy thì tất cả các biến, method điều được tạo ra và được allocate trên memory, khi memory bị cạn kiệt đồng nghĩa ứng dụng chết, do đó memory là vô cùng quan trọng nhé.
  • Trong bài viết này tìm hiểu một số loại type cũng như byte của nó trên memory của golang, sau khi biết số byte thì việc tối ưu momery là cần thiết thế nào, ta sẽ dùng SizeOf

Vidụ:

Các type và byte của nó trong golang:

package main
import (
	"fmt"
	"unsafe"
)
type Information struct {
	ValueString string
	ValueBool   bool
	ValueUint8  uint8
	ValueUint16 uint16
	ValueUint32 uint32
	ValueUint64 uint64
	ValueUint   uint
	Valueint8   int8
	Valueint16  int16
	Valueint32  int32
	Valueint64  int64
	Valueint    int
}
func main() {
	item := Information{}
	fmt.Printf("string: %+v byte \n", unsafe.Sizeof(item.ValueString))
	fmt.Printf("bool: %+v byte \n", unsafe.Sizeof(item.ValueBool))
	fmt.Println()
	fmt.Printf("uint8: %+v byte \n", unsafe.Sizeof(item.ValueUint8))
	fmt.Printf("uint16: %+v byte \n", unsafe.Sizeof(item.ValueUint16))
	fmt.Printf("uint32: %+v byte \n", unsafe.Sizeof(item.ValueUint32))
	fmt.Printf("uint64: %+v byte \n", unsafe.Sizeof(item.ValueUint64))
	fmt.Printf("uint: %+v byte \n", unsafe.Sizeof(item.ValueUint))
	fmt.Println()
	fmt.Printf("int8: %+v byte \n", unsafe.Sizeof(item.Valueint8))
	fmt.Printf("int16: %+v byte \n", unsafe.Sizeof(item.Valueint16))
	fmt.Printf("int32: %+v byte \n", unsafe.Sizeof(item.Valueint32))
	fmt.Printf("int64: %+v byte \n", unsafe.Sizeof(item.Valueint64))
	fmt.Printf("int: %+v byte \n", unsafe.Sizeof(item.Valueint))
}

=> Kết quả:

string: 16 byte

bool: 1 byte

uint8: 1 byte

uint16: 2 byte

uint32: 4 byte

uint64: 8 byte

uint: 8 byte

int8: 1 byte

int16: 2 byte

int32: 4 byte

int64: 8 byte

int: 8 byte

RUN

Với kết quả trên thì khi define các field trong golang cần quan tâm để giá trị của nó, tránh lãng phí tài nguyên.


Tối ưu khi define struct: sẽ có 2 struct và đặt vị trí field khác nhau thì sẽ có tổng số byte khác nhau:

package main

import (
	"fmt"
	"unsafe"
)

type Information struct {
	ValueUint32 uint32 // 4 byte
	ValueBool   bool   // 1 byte
	ValueUint64 uint64 // 8 byte
	ValueBool2  bool   // 1 byte
}

type Information2 struct {
	ValueUint64 uint64 // 8 byte
	ValueUint32 uint32 // 4 byte
	ValueBool   bool   // 1 byte
	ValueBool2  bool   // 1 byte
}

func main() {
	item := Information{}
	item2 := Information2{}
	fmt.Println("tong 1: ", unsafe.Sizeof(item))
	fmt.Println("tong 2: ", unsafe.Sizeof(item2))
}

tong 1: 24 tong 2: 16 => tại sao khi field là như nhau nhưng số byte lại khác nhau.

Giải Thích

  • Mặc định đối với 1 type thì cần 4byte nếu type tiếp theo cộng lại hơn 4byte.
  • Đối với struct Information; khi uint32 đứng đầu thì cần 4byte, tiếp đến là bool thì cần 1 byte nhưng cũng cần 4byte(bao gồm xử lý), uint64 thì cần 8byte, và cuối là bool thì cũng 4byte => tổng cộng là 24byte
  • Đối với struct Information2; khi uint64 đứng đầu sẽ cần 8byte, tiếp là uint32 thì cần 4byte, sau đó là 2 biến bool mỗi biến là 1 byte tổng cũng là 4byte => tổng là 16byte

Tóm Lại:

Kinh nghiệm rút ra là khi khai báo 1 struct, thì ta nên để giá trị field có byte lớn lên phía trên, còn filed byte nhỏ xuống dưới.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.