golang makeについて

藏色散人
藏色散人転載
2020-10-06 14:40:331975ブラウズ

次のコラム golang チュートリアル では、golang の make について紹介します。困っている友人の役に立てば幸いです。

golang makeについて

Golang は主に組み込み関数 new と make を通じてメモリを割り当てますが、今日は make がどのように再生できるかを見ていきます。

map は、スライス、マップ、およびチャネルにメモリを割り当て、初期化された値を返すことしかできません。まず、make の次の 3 つの異なる使用法を見てみましょう:

1. make(map[string]string)

2. make([]int, 2)

3. make([]int, 2, 4)

1. 最初の使用法は、パラメーターの長さが欠落しており、型のみが渡されることです。この使用法は、次のシナリオでのみ使用できます。タイプは map または chan です。たとえば、make([]int) はエラーを報告します。この方法で返されるスペースの長さのデフォルトは 0 です。

2. 2 番目の使用法では長さを指定します。たとえば、make([]int, 2) は長さ 2

3 のスライスを返します。3 番目の使用法、2 番目のパラメータースライスの長さを指定します。3 番目のパラメータは、予約スペースの長さを指定するために使用されます。たとえば、:= make([]int, 2, 4)。ここで注目すべき点は、返されるスライスの合計の長さです。 a は 4 です。予約とは、4 という余分な長さを意味するのではなく、実際には最初の 2 つのスライスの数を含みます。したがって、たとえば、:= make([]int, 4, 2) を使用すると、構文エラーが報告されます。

したがって、スライスにメモリを割り当てるときは、スライスの可能な最大長を推定し、make に 3 番目のパラメータを渡してスライス用のメモリ領域を予約するように最善を尽くしてください。メモリの二次割り当てによって生じるオーバーヘッドにより、プログラムのパフォーマンスが大幅に向上します。

実際には、スライスの可能な最大長を推定することは困難です。この場合、append を呼び出して要素をスライスに追加するときに、golang を使用してメモリの二次割り当てを削減します。可能な限り、毎回 1 単位のメモリ空間を増やすだけでなく、次のような拡張メカニズムに従います:

未使用領域が予約されている場合、その未使用領域はスライスに直接追加されます。スペースが使い果たされると、拡張されたスペースは現在のスライスの長さの 2 倍になります。たとえば、現在のスライスの長さは 4 です。追加操作の後、cap(a) によって返される長さは 8 になります。次のデモ コード:

package main

import (        "fmt")

func main() {
        a :=  make([]int, 0)
        n := 20
        for i := 0; i < n; i++ {
                a = append(a, 1)
                fmt.Printf("len=%d cap=%d\n", len(a), cap(a))
        }
}

Output:
len=1 cap=1  // 第一次扩容len=2 cap=2 // 第二次扩容len=3 cap=4 // 第三次扩容len=4 cap=4len=5 cap=8 // 第四次扩容len=6 cap=8len=7 cap=8len=8 cap=8len=9 cap=16 // 第五次扩容len=10 cap=16len=11 cap=16len=12 cap=16len=13 cap=16len=14 cap=16len=15 cap=16len=16 cap=16len=17 cap=32 // 第六次扩容len=18 cap=32len=19 cap=32len=20 cap=32

上記のテスト結果は、拡張するたびにメモリ空間の長さが元のサイズの 2 倍になることを示しています。

「興味があるので試してみたいと思います。このまま拡張し続けると、理論上は指数関数的に拡張します。しかし、本当にそうなるのでしょうか? 引き続き追加操作を実行し、その後の出力を実行します」

0 0
1 1
2 2
4 4
8 8
16 16
32 32
64 64
128 128
256 256
512 512
1024 1024
1312 1312    // 288
1696 1696    // 384
2208 2208    // 512
3072 3072    // 864
4096 4096    // 1024
5120 5120    // 1024
7168 7168    // 2048
9216 9216    // 2048

上記の出力は、途中に展開がない状況を無視しています。最初の 11 回の拡張では毎回長さが 2 倍になっていることがわかりますが、12 回目の拡張では明らかに予想どおり 2048 まで拡張されませんでした。

以上がgolang makeについての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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