>  기사  >  백엔드 개발  >  적절한 가비지 수집을 보장하면서 Go에서 포인터를 사용하여 태그를 이미지 URL에 효율적으로 매핑하려면 어떻게 해야 합니까?

적절한 가비지 수집을 보장하면서 Go에서 포인터를 사용하여 태그를 이미지 URL에 효율적으로 매핑하려면 어떻게 해야 합니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-10-28 17:28:29542검색

 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. 문자열 내부자 사용:

  • 메모리를 더욱 최적화하려면 문자열 내부자를 사용하여 동일한 문자열 값의 여러 복사본을 생성하지 않도록 합니다.
  • 이렇게 하면 단일 인스턴스만 각각의 고유한 문자열은 메모리에 저장됩니다.
  • 인터너가 더 이상 필요하지 않으면 캐시를 지워 보유하고 있는 문자열을 해제할 수 있습니다.

예제 코드:

<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): An 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.