Улучшенный эскейп анализ для слайсов байт полученных из строк.
Из маленького, но приятного: наконец решили и закрыли одну из четырехзначных задач (сие значит очень старая задача, скорее всего еще из старого трекера) - #2205 read-only escape analysis and avoiding string -> []byte copies.
Допустим у вас есть код:package main
import (
"strings"
"testing"
)
var Index int
func BenchmarkStrToSlice(b *testing.B) {
someStr := strings.Repeat("HELLO WORLD", 6)
for i := 0; i < b.N; i++ {
Index = indexByte([]byte(someStr), 'D')
}
}
func indexByte(s []byte, c byte) int {
// Я про bytes.IndexByte(s, c) которая быстрее.
// Эта функция здесь находится для демонстрации.
for i, b := range s {
if b == c {
return i
}
}
return -1
}
Сейчас вызов go test -benchmem -bench .
выдаст примерно такие результаты:BenchmarkStrToSlice-10
46341886
22.75 ns/op
80 B/op
1 allocs/op
По копии на каждую итерацию. А все из-за того, что при преобразовании из строки в слайс байт, эскейп анализ предполагает, что мы будем этот слайс байт по всякому редактировать. А раз строки у нас неизменяемые, то значит надо бы скопировать всю строку в новый слайс перед передачей его дальше в функцию. Это, в свою очередь, приводит к полной копии строки, что в чутких к производительности местах может быть довольно неприятно.
Однако уже в Go 1.22 эксейп анализ научится пробегать дерево вызываемых функций и пытаться доказать, что слайс байт мы все же не меняем (или эта строка нигде более не используется). И как следствие, копию можно уже не делать.
На gotip test -benchmem -bench .
результаты обнадеживают:BenchmarkStrToSlice-10 248279863. 4.707 ns/op 0 B/op 0 allocs/op
Никаких больше копий при конвертации из строки в слайс, если мы будем только читать из слайса.
>>Click here to continue<<