ホームページ  >  記事  >  バックエンド開発  >  Go プログラムで文字列とポインターを操作するときにメモリ使用量とガベージ コレクションを最適化するにはどうすればよいですか?

Go プログラムで文字列とポインターを操作するときにメモリ使用量とガベージ コレクションを最適化するにはどうすればよいですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-04 04:10:30879ブラウズ

 How can I optimize memory usage and garbage collection in my Go program when working with strings and pointers?

Go におけるガベージ コレクションとポインターの正しい使用法

ガベージ コレクションの背景

Go はガベージ コレクターを使用してメモリを自動的に管理します。ガベージ コレクターは、ポインターによって参照されなくなったメモリを解放します。

ポインターと文字列

Go では、文字列は値によって渡される不変の値です。関数が文字列を受け取ると、元の文字列への参照ではなく、文字列の値のコピーを受け取ります。

ポインターの使用

提供されたコードでは、次のバージョンのマッピング コードが使用されます。

バージョン 1:

tagToUrlMap := make(map[string][]*string)

for _, image := range result {
    for _, tag := range image.Tags {
        tagToUrlMap[tag.Name] = append(tagToUrlMap[tag.Name], &image.URL)
    }
}

バージョン 2:

tagToUrlMap := make(map[string][]*string)

for _, image := range result {
    imageUrl = image.URL
    for _, tag := range image.Tags {
        tagToUrlMap[tag.Name] = append(tagToUrlMap[tag.Name], &imageUrl)
    }
}

問題:

  • どちらのバージョンでも、Image 構造体の URL フィールドのアドレスを保存すると、Image 構造体がガベージ コレクションされるのを防ぎます。
  • バージョン 2 では追加の間接レベルが導入され、不要なオブジェクトの割り当て。

最適な解決策

最適な解決策は、次のコードを使用することです。

tagToUrlMap := make(map[string][]string)

for _, image := range result {
    imageURL := image.URL // Store the string value directly

    for _, tag := range image.Tags {
        tagName := tag.Name  // Store the string value directly
        tagToUrlMap[tagName] = append(tagToUrlMap[tagName], imageURL)
    }
}

String Interning

このコード検出された URL とタグ名ごとに新しい文字列を作成します。メモリ使用量をさらに最適化するには、文字列インターニングを使用できます。

文字列インターニングには、一意の文字列値を中央キャッシュに保存することが含まれます。新しい文字列が見つかると、キャッシュと照合してチェックされます。文字列がすでにキャッシュ内にある場合は、新しい文字列を作成する代わりに、キャッシュされた値が使用されます。

これは単純な文字列内部です:

var cache = map[string]string

func intern(s string) string {
    if s2, ok := cache[s]; ok {
        return s2
    }
    cache[s] = s
    return s
}

内部を使用するには、次のようなマッピング コード:

tagToUrlMap := make(map[string][]string)

for _, image := range result {
    imageURL := intern(image.URL) // Intern the string

    for _, tag := range image.Tags {
        tagName := intern(tag.Name) // Intern the string
        tagToUrlMap[tagName] = append(tagToUrlMap[tagName], imageURL)
    }
}

キャッシュのクリア

インターニングのキャッシュによって使用されているメモリを解放するには、インターニングが完了したらキャッシュ変数に nil を割り当てます:

cache = nil

さらなる最適化

  • tagToUrlMap を構築した後、マップ内のスライスから余分な容量をトリミングしてメモリを節約します。
  • 必要に応じて、カスタム メモリ アロケータを使用してさらに最適化します。メモリ使用量。

結論

文字列値を直接使用し、文字列インターニングし、インターナーのキャッシュをクリアすることで、Go プログラムで最適なメモリ使用量と効率的なガベージ コレクションを実現できます。

以上がGo プログラムで文字列とポインターを操作するときにメモリ使用量とガベージ コレクションを最適化するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。