ホームページ  >  記事  >  バックエンド開発  >  適切なガベージ コレクションを確保しながら、Go でポインターを使用してタグを画像 URL に効率的にマッピングするにはどうすればよいですか?

適切なガベージ コレクションを確保しながら、Go でポインターを使用してタグを画像 URL に効率的にマッピングするにはどうすればよいですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-10-28 17:28:29534ブラウズ

 How can I efficiently map tags to image URLs using pointers in Go while ensuring proper garbage collection?

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

問題:

Python などの異なるデータ構造を持つ言語を使用していて、Go に移行したいと考えています。 Go プログラムでポインタを適切に活用する方法がわかりません。

具体的には、次のような状況があります。

  • 大規模な JSON 応答がある画像データと対応するタグを使用します。
  • 各タグを画像 URL のリストにマップするには、Go でデータ構造を作成する必要があります。
  • ポインターを使用してメモリ使用量を最適化したいと考えています。

質問:

Go プログラムでタグを画像 URL にマッピングするためにポインタを効果的に使用するにはどうすればよいですか?適切なガベージ コレクションとメモリ管理を確保するには、どのような考慮事項を考慮する必要がありますか?

答え:

1.フィールドへのポインタの保存を避ける:

  • 構造体内の特定のフィールドへのポインタを保存することは可能ですが、推奨されません。
  • 構造体全体は次のようにメモリ内に保持されます。特定のフィールドのみが必要な場合でも、ポインタが生きている限り。
  • これにより、不要なメモリの断片化が発生する可能性があります。

2.文字列値はポインタのように動作します:

  • Go の文字列値は、実際の文字列データへのポインタを含む reflect.StringHeader という小さな構造体によって表されます。
  • 文字列を渡すかコピーするときは、文字列データ全体ではなく、基本的にこの reflect.StringHeader 構造体を渡すかコピーすることになります。
  • これは、文字列値がすでにポインタのように機能することを意味します。

3.文字列インナーを使用します:

  • メモリをさらに最適化するには、文字列インナーを使用して、同じ文字列値の複数のコピーが作成されるのを防ぎます。
  • これにより、インスタンスが 1 つだけになることが保証されます。それぞれの一意の文字列がメモリに保存されます。
  • 内部が不要になったら、そのキャッシュをクリアして、内部に保持されている文字列を解放できます。

コード例:

<code class="go">package main

import (
    "encoding/json"
    "fmt"
    "os"
    "reflect"
)

type Image struct {
    URL        string
    Description string
    Tags        []*Tag
}

type Tag struct {
    Name string
    Rank int
}

// this function mimics json.NewDecoder(resp.Body).Decode(&amp;parsedJSON)
func searchImages() []*Image {
    parsedJSON := []*Image{
        &amp;Image{
            URL:        "https://c8.staticflickr.com/4/3707/11603200203_87810ddb43_o.jpg",
            Description: "Ocean islands",
            Tags: []*Tag{
                &amp;Tag{"ocean", 1},
                &amp;Tag{"water", 2},
                &amp;Tag{"blue", 3},
                &amp;Tag{"forest", 4},
            },
        },
        &amp;Image{
            URL:        "https://c3.staticflickr.com/1/48/164626048_edeca27ed7_o.jpg",
            Description: "Bridge over river",
            Tags: []*Tag{
                &amp;Tag{"bridge", 1},
                &amp;Tag{"river", 2},
                &amp;Tag{"water", 3},
                &amp;Tag{"forest", 4},
            },
        },
    }
    return parsedJSON
}

func main() {
    result := searchImages()

    cache := map[string]string{}

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

    for _, image := range result {
        imageURL := intern(image.URL, cache)

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

    cache = nil

    enc := json.NewEncoder(os.Stdout)
    enc.SetIndent("", "  ")
    if err := enc.Encode(tagToUrlMap); err != nil {
        panic(err)
    }
}

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

    // New string, store it
    cache[s] = s
    return s
}</code>

追加リソース:

  • [Go のポインター](https://go.dev/blog/pointers): Go のポインターの紹介。
  • [Effective Go](https://go.dev/doc/Effective_go): 慣用的な Go コードを記述するためのガイド。
  • [Go のガベージ コレクション] (https://dave.cheney.net/2013/06/03/garbage-collection-in-go): Go のガベージ コレクションの詳細な説明。

以上が適切なガベージ コレクションを確保しながら、Go でポインターを使用してタグを画像 URL に効率的にマッピングするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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