TG Telegram Group & Channel
Go Update | United States America (US)
Create: Update:

Улучшенный эскейп анализ для слайсов байт полученных из строк.

Из маленького, но приятного: наконец решили и закрыли одну из четырехзначных задач (сие значит очень старая задача, скорее всего еще из старого трекера) - #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

Никаких больше копий при конвертации из строки в слайс, если мы будем только читать из слайса.

Улучшенный эскейп анализ для слайсов байт полученных из строк.

Из маленького, но приятного: наконец решили и закрыли одну из четырехзначных задач (сие значит очень старая задача, скорее всего еще из старого трекера) - #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<<

Go Update




Share with your best friend
VIEW MORE

United States America Popular Telegram Group (US)