Maison >développement back-end >Golang >Comment puis-je mapper efficacement les balises aux URL d'images à l'aide de pointeurs dans Go tout en garantissant un garbage collection approprié ?

Comment puis-je mapper efficacement les balises aux URL d'images à l'aide de pointeurs dans Go tout en garantissant un garbage collection approprié ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-28 17:28:29624parcourir

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

Garbage Collecte et utilisation correcte des pointeurs dans Go

Problème :

Vous êtes vous travaillez avec un langage avec une structure de données différente, comme Python, et vous souhaitez migrer vers Go. Vous ne savez pas comment exploiter correctement les pointeurs dans un programme Go.

Plus précisément, vous vous trouvez dans une situation où :

  • Vous avez une réponse JSON volumineuse avec les données d'image et les balises correspondantes.
  • Vous devez créer une structure de données dans Go pour mapper chaque balise à une liste d'URL d'image.
  • Vous souhaitez utiliser des pointeurs pour optimiser l'utilisation de la mémoire.
Vous souhaitez utiliser des pointeurs pour optimiser l'utilisation de la mémoire.

Question :

Comment utiliser efficacement les pointeurs pour mapper les balises aux URL d'images dans un programme Go ? Quelles considérations doivent être prises pour garantir une bonne collecte des ordures et une bonne gestion de la mémoire ?

Réponse :

1. Évitez de stocker des pointeurs vers des champs :
  • Bien qu'il soit possible de stocker des pointeurs vers des champs spécifiques dans une structure, cela n'est pas recommandé.
  • La structure entière sera conservée en mémoire comme tant que le pointeur est vivant, même si vous n'avez besoin que d'un champ spécifique.
Cela peut entraîner une fragmentation indésirable de la mémoire.

2. Les valeurs de chaîne se comportent comme des pointeurs :
  • Les valeurs de chaîne dans Go sont représentées par de petites structures appelées
  • reflect.StringHeader
  • contenant un pointeur vers les données de chaîne réelles.Lorsque vous transmettez ou copiez une chaîne, vous transmettez ou copiez essentiellement cette structure
  • reflect.StringHeader
  • , et non l'intégralité des données de la chaîne.
Cela signifie que les valeurs de chaîne agissent déjà comme des pointeurs.

3. Utilisez un interne de chaîne :
  • Pour optimiser davantage la mémoire, utilisez un interne de chaîne pour éviter de créer plusieurs copies de la même valeur de chaîne.
  • Cela garantit qu'une seule instance de chaque chaîne unique est stockée en mémoire.
Une fois que l'interner n'est plus nécessaire, vous pouvez vider son cache pour libérer les chaînes qu'il contient.

Exemple de code :
<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>

Ressources supplémentaires :
  • [Pointeurs dans Go](https://go.dev/blog/pointers) : Un introduction aux pointeurs dans Go.
  • [Effective Go](https://go.dev/doc/effective_go) : Un guide pour écrire du code Go idiomatique.
[Garbage Collection in Go] (https://dave.cheney.net/2013/06/03/garbage-collection-in-go) : Une explication détaillée de la collecte des ordures dans Go.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn