Maison > Article > développement back-end > Pourquoi la reconversion de « interface{} » en tranche entraîne-t-elle une allocation de tas supplémentaire ?
En PHP, lors de la conversion du type "interface{}" en type slice, cela entraînera une allocation de tas supplémentaire. En effet, en PHP, une interface est un type de données abstrait et une tranche est un type de tableau dynamique. Lorsque nous convertissons un type d'interface en type slice, PHP doit allouer de l'espace mémoire supplémentaire au type slice afin de stocker les éléments de la tranche. Cette opération d'allocation de tas supplémentaire entraînera une surcharge de mémoire supplémentaire, ce qui peut entraîner des problèmes de performances pour certaines applications sensibles à la mémoire. Par conséquent, lors de la conversion de type, nous devons prêter attention à ce problème et essayer d'éviter une allocation de tas supplémentaire inutile.
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) } }
Ce benchmark donne le résultat suivant dans go1.19.5.
benchmarkpool benchmarkpool-10 47578498 24.47 ns/op 24 b/op 1 allocs/op
Les choses semblent différentes lors de l'utilisation de *[]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
Il semble que la reconversion de interface{}
en tranche entraîne des allocations de tas supplémentaires.
Pourquoi Go a-t-il besoin de cette allocation supplémentaire ? Quelles sont les considérations de conception derrière cela ?
Ce n'est pas any
到 []byte
的转换,而是 []byte
到 any
的转换。 p.Put(bts)
将参数 bts
隐式转换为 any
,然后再将其传递给 (*sync.Pool).Put
qui provoque l'allocation. L'interface de GoGC 1.19 est implémentée sous la forme d'une paire de pointeurs, l'un pointant vers les métadonnées de type et l'autre vers l'objet réel. Dans ce cas, le deuxième pointeur est échappé vers le pool, provoquant l'allocation de l'objet slice. Cela s'applique non seulement aux types de tranches, mais également à tout autre type non pointeur.
Pour les pointeurs, tels que *[]byte
,编译器会执行优化,将其值直接放入 iface
结构中,从而在转换为接口时删除 *[]byte
, le compilateur effectue une optimisation en plaçant sa valeur directement dans la structure iface
, supprimant ainsi l'allocation de l'instance
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!