Mengapakah menukar 'antara muka{}' kembali kepada kepingan menghasilkan peruntukan timbunan tambahan?

PHPz
Lepaskan: 2024-02-12 22:15:09
ke hadapan
719 orang telah melayarinya

Mengapakah menukar antara muka{} kembali kepada kepingan menghasilkan peruntukan timbunan tambahan?

Dalam PHP, apabila menukar jenis "antara muka{}" kepada jenis kepingan, ia akan menyebabkan peruntukan timbunan tambahan. Ini kerana dalam PHP, antara muka ialah jenis data abstrak, dan kepingan ialah jenis tatasusunan dinamik. Apabila kita menukar jenis antara muka kepada jenis kepingan, PHP perlu memperuntukkan ruang memori tambahan untuk jenis kepingan untuk menyimpan elemen kepingan. Operasi peruntukan timbunan tambahan ini akan menyebabkan overhed memori tambahan, yang mungkin menyebabkan isu prestasi untuk beberapa aplikasi sensitif memori. Oleh itu, apabila melakukan penukaran jenis, kita harus memberi perhatian kepada isu ini dan cuba mengelakkan peruntukan timbunan tambahan yang tidak perlu.

Isi soalan

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)
    }
}
Salin selepas log masuk

Tanda aras ini memberikan output berikut dalam go1.19.5.

benchmarkpool
benchmarkpool-10        47578498            24.47 ns/op       24 b/op          1 allocs/op
Salin selepas log masuk

Benda nampak berbeza bila guna *[]byte:

func benchmarkpool(b *testing.b) {
    b.reportallocs()
    p := sync.pool{new: func() interface{} {
        bts := make([]byte, 1024)
        return &bts
    }}
    for i := 0; i < b.n; i++ {
        bts := p.get().(*[]byte)
        p.put(bts)
    }
}
Salin selepas log masuk
BenchmarkPool
BenchmarkPool-10        142008002            8.581 ns/op           0 B/op          0 allocs/op
Salin selepas log masuk

Nampaknya menukar interface{} kembali kepada kepingan menghasilkan peruntukan timbunan tambahan.

Mengapa pergi memerlukan peruntukan tambahan ini? Apakah pertimbangan reka bentuk di sebalik ini?

Penyelesaian

Bukan any[]byte 的转换,而是 []byteany 的转换。 p.Put(bts) 将参数 bts 隐式转换为 any,然后再将其传递给 (*sync.Pool).Put yang menyebabkan peruntukan. Antara muka dalam GoGC 1.19 dilaksanakan sebagai sepasang penunjuk, satu menunjuk ke jenis metadata dan satu menunjuk ke objek sebenar, dalam kes ini penuding kedua terlepas ke kolam, menyebabkan objek hirisan diperuntukkan. Ini terpakai bukan sahaja untuk jenis hirisan, tetapi juga kepada mana-mana jenis bukan penuding lain.

Untuk penunjuk, seperti *[]byte,编译器会执行优化,将其值直接放入 iface 结构中,从而在转换为接口时删除 *[]byte, pengkompil melakukan pengoptimuman dengan meletakkan nilainya terus ke dalam struktur iface, dengan itu mengalih keluar peruntukan contoh

apabila menukar kepada antara muka. Oleh itu, secara amnya disyorkan untuk meletakkan penunjuk ke dalam kolam dan bukannya struktur itu sendiri. 🎜

Atas ialah kandungan terperinci Mengapakah menukar 'antara muka{}' kembali kepada kepingan menghasilkan peruntukan timbunan tambahan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!