Портрет 4X_Pro
Был в Сети 1 сент. 2025 г., 05:42
Мультиблог
4X_Pro
Кратко о себе: Web-разработчик. Пишу на PHP, Python, JavaScript. Знаю Ruby и Go, со студенческих времён более-менее помню C и asm. Специализируюсь на ускорении загрузки сайтов и разработке ботов для Telegram. Linuxоид (использую Debian+LXDE). Сторонник IndieWeb, slow lifer.

Социальные сети


Новости сайта в Telegram

t.me/4x_pro

Компьютерное

Преобразование массива байтов в строку на Go

4X_Pro

Занимаясь разработкой SiteKnockerBot для мониторинга сайтов, я столкнулся с тем, что результат HTTP-запроса в Go читается в массив (вернее, slice) байтов. Но для дальнейшей обработки требовалось преобразовать его в строку. На первый взгляд казалось, что это просто — достаточно воспользоваться приведением типов:
str:=string(bytes_array[:]);
Скоро выяснилось, что это плохо с точки зрения производительности: для переменной str будет выделена новая область памяти, куда будет скопировано всё содержимое bytes_array. Если объем данных значителен или одновременно выполняется множество goroutines, то выполнение ощутимо замедляется (в моём случае среднее время обработки запроса увеличивалось почти на 100 мс). Возник вопрос: можно ли как-то преобразовать массив без копирования. После недолгих поисков в Интернете нашлось решение, реализованное через небезопасную работу с указателями:
func bytesToString(b []byte) string {     bh := (*reflect.SliceHeader)(unsafe.Pointer(&b));     sh := reflect.StringHeader{bh.Data, bh.Len};     return *(*string)(unsafe.Pointer(&sh)); } str:=bytesToString(bytes_array);
Работает этот код так: берет указатель на заголовок slice, извлекает из него длину и указатель на данные, и записывает в аналогичную структуру для строки, а потом возвращает её из функции. Для того, чтобы код скомпилировался, нужно в import указать "reflect" и "unsafe".


Задать вопрос

Здесь можно задать мне вопрос или спросить совета по любой теме, затронутой в блогах или на форуме. После того, как я отвечу, вопрос и ответ появятся в соответствующем разделе. Но не забываем, что я — сторонник slow life, поэтому каких-либо сроков ответов не обещаю. Самые интересные вопросы станут основой для новых тем на форуме или записей в блоге.
Сразу предупреждаю: глупости, провокации, троллинг и тому подобное летит прямо в /dev/null.