'인터페이스{}'를 다시 슬라이스로 변환하면 추가 힙 할당이 발생하는 이유는 무엇입니까?

PHPz
풀어 주다: 2024-02-12 22:15:09
앞으로
719명이 탐색했습니다.

인터페이스{}를 다시 슬라이스로 변환하면 추가 힙 할당이 발생하는 이유는 무엇입니까?

PHP에서는 "인터페이스{}" 유형을 슬라이스 유형으로 변환할 때 추가 힙 할당이 발생합니다. 이는 PHP에서 인터페이스는 추상 데이터 유형이고 슬라이스는 동적 배열 유형이기 때문입니다. 인터페이스 유형을 슬라이스 유형으로 변환할 때 PHP는 슬라이스 요소를 저장하기 위해 슬라이스 유형에 추가 메모리 공간을 할당해야 합니다. 이러한 추가 힙 할당 작업으로 인해 추가 메모리 오버헤드가 발생하여 일부 메모리에 민감한 애플리케이션에 성능 문제가 발생할 수 있습니다. 따라서 타입 변환을 수행할 때 이 문제에 주의하고 불필요한 추가 힙 할당을 피하도록 노력해야 합니다.

질문 내용

func benchmarkpool(b *testing.b) {
    b.reportallocs()
    p := sync.pool{new: func() interface{} {
        return make([]byte, 1024)
    }}
    for i := 0; i < b.n; i++ {
        bts := p.get().([]byte)
        p.put(bts)
    }
}
로그인 후 복사

이 벤치마크는 go1.19.5에서 다음과 같은 출력을 제공합니다.

으아악

사용하면 상황이 다르게 보입니다. *[]byte:

으아악 으아악

interface{} 다시 슬라이스로 변환하면 추가 힙 할당이 발생하는 것 같습니다.

왜 go에 이러한 추가 할당이 필요한가요? 이에 대한 디자인 고려 사항은 무엇입니까?

해결책

할당의 원인은 any[]byte 的转换,而是 []byteany 的转换。 p.Put(bts) 将参数 bts 隐式转换为 any,然后再将其传递给 (*sync.Pool).Put아닙니다. GoGC 1.19의 인터페이스는 한 쌍의 포인터로 구현됩니다. 하나는 유형 메타데이터를 가리키고 다른 하나는 실제 개체를 가리킵니다. 이 경우 두 번째 포인터가 풀로 이스케이프되어 슬라이스 개체가 할당됩니다. 이는 슬라이스 유형뿐만 아니라 포인터가 아닌 다른 유형에도 적용됩니다.

*[]byte,编译器会执行优化,将其值直接放入 iface 结构中,从而在转换为接口时删除 *[]byte와 같은 포인터의 경우 컴파일러는 해당 값을 iface 구조에 직접 배치하여 최적화를 수행하므로 인터페이스로 변환할 때

인스턴스 할당을 제거합니다. 따라서 일반적으로 포인터를 구조체 자체보다는 풀에 넣는 것이 좋습니다. 🎜

위 내용은 '인터페이스{}'를 다시 슬라이스로 변환하면 추가 힙 할당이 발생하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:stackoverflow.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!