ホームページ >バックエンド開発 >Golang >golang でのバイトアライメントの使用方法の詳細な説明

golang でのバイトアライメントの使用方法の詳細な説明

藏色散人
藏色散人転載
2021-09-10 16:42:152405ブラウズ

この記事は go language チュートリアル コラムで golang のバイト アライメントを紹介する記事として紹介されています。

最近、パフォーマンスの最適化作業を行っています。構造体の 1 つは比較的大きなスペースを占有しており、メモリ内の数は非常に多くなっています。特殊です。何か最適化の余地はないかと考えていたところ、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 ですがtype には 1 桁しかありませんが、コンピュータはバイト単位の
  • 64 マシンであるため、1 バイトも占有する必要があります。int は 8 バイトを占有します。
  • string 型は 16 バイトを占有し、内部には次の値が含まれます。データへのポインタ (8 バイト) と int の長さ (8 バイト)
  • スライス タイプは 24 バイトを占め、内部にはデータへのポインタ (8 バイト) と int の長さ (8 バイト) ) と int (8 バイト) の容量
  • マップ型は 8 バイトを占め、マップ構造へのポインタです
  • はい空の型を表すには struct{} を使用します。この型はスペースを占有しません。これをマップの値として使用します。マップをセットとして使用して、構造体で
バイト アラインメント

を使用できます。 のフィールドは存在しません。メモリ上にコンパクトに配置されていますが、バイト単位でアライメントされています。たとえば、int が 8 バイトを占める場合、8 の倍数のアドレスにのみ書き込むことができます。なぜバイトアライメントが必要かというと、主に効率上の理由からですが、インターネットで詳細な原理を読んだ後、あまり信頼性が低いと感じたので、くだらない話はしませんが、興味があれば自分で勉強してください

// |x---|
So(unsafe.Sizeof(struct {
    i8 int8
}{}), ShouldEqual, 1)
単に int8 構造体をカプセル化するだけです。 int8 では、1 バイトしか占有せず、余分なスペースはありません。

// |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)
2 つの構造体の内容はまったく同じです。フィールドの順序が調整され、スペースの 33% が節約されています。

// |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)
ここで、int64 は 8 の倍数のアドレスにのみ出現できることに注意してください。そのため、最初の構造体には空の連続バイトが 4 つあります。

type I8 int8
type I16 int16
type I32 int32

So(unsafe.Sizeof(struct {
    i8  I8
    i16 I16
    i32 I32
}{}), ShouldEqual, 8)
型の名前を変更すると、型はサイズは変更されていません。

golang 関連の知識については、

golangチュートリアル列をご覧ください!

以上がgolang でのバイトアライメントの使用方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。