Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah menukar "antara muka{}" kembali kepada kepingan menghasilkan peruntukan timbunan tambahan?

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

PHPz
PHPzke hadapan
2024-02-12 22:15:09733semak imbas

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)
    }
}

Tanda aras ini memberikan output berikut dalam go1.19.5.

benchmarkpool
benchmarkpool-10        47578498            24.47 ns/op       24 b/op          1 allocs/op

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)
    }
}
BenchmarkPool
BenchmarkPool-10        142008002            8.581 ns/op           0 B/op          0 allocs/op

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!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam