Forwarded from Код и Капуста
zero-copy-оптимизации
#golang
Разбор zero-copy-оптимизаций в Go.
Когда вы передаете
Для проксирования сокет-в-сокет та же логика работает через
https://kodikapusta.ru/news/1108-zero-copy-optimizatsii
Поддержать проект на boosty и читать в MAX
#golang
Разбор zero-copy-оптимизаций в Go.
Когда вы передаете
*os.File напрямую в io.Copy(conn, f), рантайм распознает это через цепочку type-assertions и вызывает sendfile(2), передавая данные из кеша странички в сокет без копирования в юзерспейсе. Но вот когда вы оборачиваете *os.File в свой собственный io.Reader, то все становится не так радужно. В тестах использование *os.File дает прирост в ~54 мс CPU на гигабайт и ~3 000 сисколлов против 184 мс CPU и 131 000 сисколлов при оборачивании файла в любой пользовательский io.Reader. Единственная "бесплатная" обертка это io.LimitedReader, которую рантайм явно разворачивает. Для проксирования сокет-в-сокет та же логика работает через
splice(2), но любая промежуточная обертка ломает fast path, и диагностировать это проще всего через strace -c. Сотни тысяч пар read/write означают, что zero-copy не работает в вашем кодеhttps://kodikapusta.ru/news/1108-zero-copy-optimizatsii
Поддержать проект на boosty и читать в MAX
👍3👏2❤1
Тут человечек решил собрать своего гофера. Да не простого, а из деталек которые совместимы с ЛЕГО. Юра (так зовут создателя) вместе со студией разработки наборов StarBricks спроектировал модель, и вчера запустил сбор на неё на старейшем краудфандинге в РФ.
Выглядит слегка эклектично, но может зайти. Если вы всегда хотели посадить гофера вна модельку стар-дейстроера из звездных войн, то у вас есть отличный момент для реализации своей идеи.
Больше информации в канале.
Выглядит слегка эклектично, но может зайти. Если вы всегда хотели посадить гофера вна модельку стар-дейстроера из звездных войн, то у вас есть отличный момент для реализации своей идеи.
Больше информации в канале.
👍4👎2
Forwarded from Код и Капуста
Джину уже 12 лет
#golang
Ману Мартинес-Алмейда рассказывает историю как он создавал Gin - одного из самых популярных веб-фреймворков для Go, который вырос из его несостоявшегося стартапа Fyve и разрабатывался по принципу "простое важнее легкого".
Вдохновившись выступлением Роба Пайка, он противопоставил Gin фреймворку Martini. Вместо рефлексии и магии - явный gin.Context, который нес все нужное для обработки запроса и появился за два года до стандартного context.Context, а вместо обхода списка регулярных выражений на каждый запрос - radix-дерево для маршрутизации с константным временем поиска, не зависящим от количества маршрутов.
Как быстро растут чужие фреймворки
https://kodikapusta.ru/news/1105-dzhinu-uzhe-12-let
Поддержать проект на boosty и читать в MAX
#golang
Ману Мартинес-Алмейда рассказывает историю как он создавал Gin - одного из самых популярных веб-фреймворков для Go, который вырос из его несостоявшегося стартапа Fyve и разрабатывался по принципу "простое важнее легкого".
Вдохновившись выступлением Роба Пайка, он противопоставил Gin фреймворку Martini. Вместо рефлексии и магии - явный gin.Context, который нес все нужное для обработки запроса и появился за два года до стандартного context.Context, а вместо обхода списка регулярных выражений на каждый запрос - radix-дерево для маршрутизации с константным временем поиска, не зависящим от количества маршрутов.
Как быстро растут чужие фреймворки
https://kodikapusta.ru/news/1105-dzhinu-uzhe-12-let
Поддержать проект на boosty и читать в MAX
👎3🔥1😁1
Forwarded from Код и Капуста
Активация сокетов
#golang
Автор рассказывает, как с помощью сокет-активации systemd запускать Go-сервис только когда в него реально приходит запрос, чтобы не тратить память и CPU.
systemd сам открывает и слушает сокет на нужном порту, а при первом подключении запускает сервер, передавая ему уже открытый файловый дескриптор вместе с переменными окружения LISTEN_PID и LISTEN_FDS. В Go это можно сделать вручную через net.FileListener, но удобнее использовать пакет coreos/go-systemd, который через activation.Listeners() сразу отдает готовый net.Listener.
Можно наколбасить решение, которое сможет работать и без активации, при этом использовать фишечки systemd через daemon.SdNotify() и будет завершает работу после нескольких секунд простоя с помощью отдельной горутины с таймером. В итоге сервис будет стартовать по первому запросу и автоматически выключается при бездействии, освобождая ресурсы
https://kodikapusta.ru/news/1113-aktivatsiia-soketov
Поддержать проект на boosty и читать в MAX
#golang
Автор рассказывает, как с помощью сокет-активации systemd запускать Go-сервис только когда в него реально приходит запрос, чтобы не тратить память и CPU.
systemd сам открывает и слушает сокет на нужном порту, а при первом подключении запускает сервер, передавая ему уже открытый файловый дескриптор вместе с переменными окружения LISTEN_PID и LISTEN_FDS. В Go это можно сделать вручную через net.FileListener, но удобнее использовать пакет coreos/go-systemd, который через activation.Listeners() сразу отдает готовый net.Listener.
Можно наколбасить решение, которое сможет работать и без активации, при этом использовать фишечки systemd через daemon.SdNotify() и будет завершает работу после нескольких секунд простоя с помощью отдельной горутины с таймером. В итоге сервис будет стартовать по первому запросу и автоматически выключается при бездействии, освобождая ресурсы
https://kodikapusta.ru/news/1113-aktivatsiia-soketov
Поддержать проект на boosty и читать в MAX
🔥3
Forwarded from Код и Капуста
На 49% быстрее из-за выравнивания
#golang
Разбор неожиданной оптимизации в Go: сдвиг массива на 4 байта через добавление padding-поля ускоряет операцию обнуления на 49% на Intel и на 9% на AMD. Обнуляция - это что-то типо
Но почему так происходит? Компилятор генерирует инструкцию REP STOSQ, чей механизм Enhanced REP (ERMSB) записывает целые кэш-строки без предварительного чтения, но только при 8-байтном выравнивании адреса - при смещении. Добавление 4 байт как раз выравнивает позицию массива по 8 в примере автора.
Не уверен что вам это пригодиться, но мне нравятся люди, которы зелазют так глубоко в кишки к байтам и битам
https://kodikapusta.ru/news/1114-49-bystree-iz-za-vyravnivaniia
Поддержать проект на boosty и читать в MAX
#golang
Разбор неожиданной оптимизации в Go: сдвиг массива на 4 байта через добавление padding-поля ускоряет операцию обнуления на 49% на Intel и на 9% на AMD. Обнуляция - это что-то типо
b.data = [words]uint32{}Но почему так происходит? Компилятор генерирует инструкцию REP STOSQ, чей механизм Enhanced REP (ERMSB) записывает целые кэш-строки без предварительного чтения, но только при 8-байтном выравнивании адреса - при смещении. Добавление 4 байт как раз выравнивает позицию массива по 8 в примере автора.
Не уверен что вам это пригодиться, но мне нравятся люди, которы зелазют так глубоко в кишки к байтам и битам
https://kodikapusta.ru/news/1114-49-bystree-iz-za-vyravnivaniia
Поддержать проект на boosty и читать в MAX
❤3
Forwarded from Код и Капуста
TypeScript переписали на Go
#golang
Команда Microsoft с помощью AI переписала компилятор TypeScript 7.0 на Go, а не на Rust (шах и мат!). Команда добилась примерно десятикратного ускорения сборки, и автор использует это как повод доказать, что Go - оптимальный язык для эпохи агентной разработки с использованием ИИ.
Go изначально спроектирован ради читателя, а не писателя кода. И это свойство идеально подходит большим языковым моделям, которые читают код гораздо больше, чем люди (что печально). Автор разбирает четыре накапливающиеся проблемы, которые Go решает лучше Python и TypeScript: медленная сборка, недетерминированное управление зависимостями, слабая обратная связь по ошибкам и постоянная нестабильность экосистемы.
Вот видите, есть еще порох в пороховницах! Все на Go перепишем
https://kodikapusta.ru/news/1119-typescript-perepisali-na-go
Поддержать проект на boosty и читать в MAX
#golang
Команда Microsoft с помощью AI переписала компилятор TypeScript 7.0 на Go, а не на Rust (шах и мат!). Команда добилась примерно десятикратного ускорения сборки, и автор использует это как повод доказать, что Go - оптимальный язык для эпохи агентной разработки с использованием ИИ.
Go изначально спроектирован ради читателя, а не писателя кода. И это свойство идеально подходит большим языковым моделям, которые читают код гораздо больше, чем люди (что печально). Автор разбирает четыре накапливающиеся проблемы, которые Go решает лучше Python и TypeScript: медленная сборка, недетерминированное управление зависимостями, слабая обратная связь по ошибкам и постоянная нестабильность экосистемы.
Вот видите, есть еще порох в пороховницах! Все на Go перепишем
https://kodikapusta.ru/news/1119-typescript-perepisali-na-go
Поддержать проект на boosty и читать в MAX
😁4
Forwarded from Код и Капуста
mmap или pread
#golang
Автор статьи - инженер из VictoriaMetrics. На примере реального движка хранения VictoriaLogs разбирает выбор между системным вызовом pread и отображением файла в память mmap при чтении байтов из файлов.
Автор объясняет, что pread имеет заметную цену: каждый вызов - это дорогой переход из пользовательского пространства в ядро с копированием данных, и при миллионе мелких случайных чтений на один запрос теряется целая секунда процессорного времени только на пересечение границы ядра.
Mmap превращает эти чтения в дешевый доступ к памяти, но у него есть коварная проблема именно для Go: обращение к "холодной" странице вызывает major page fault, который блокирует поток ОС незаметно для планировщика Go. При достаточном числе таких блокировок программа может застопориться.
В итоге, оптимальное решение - это абстракция ReaderAt, которая через системный вызов mincore проверяет, находится ли нужная страница уже в оперативной памяти. Если да, то используется быстрый mmap-путь, а если нет - то безопасный pread. При этом результаты mincore кэшируются в битовой карте на срок до минуты.
В статье еще разбирается целая куча самых разных тонкостей
https://kodikapusta.ru/news/1120-mmap-ili-pread
Поддержать проект на boosty и читать в MAX
#golang
Автор статьи - инженер из VictoriaMetrics. На примере реального движка хранения VictoriaLogs разбирает выбор между системным вызовом pread и отображением файла в память mmap при чтении байтов из файлов.
Автор объясняет, что pread имеет заметную цену: каждый вызов - это дорогой переход из пользовательского пространства в ядро с копированием данных, и при миллионе мелких случайных чтений на один запрос теряется целая секунда процессорного времени только на пересечение границы ядра.
Mmap превращает эти чтения в дешевый доступ к памяти, но у него есть коварная проблема именно для Go: обращение к "холодной" странице вызывает major page fault, который блокирует поток ОС незаметно для планировщика Go. При достаточном числе таких блокировок программа может застопориться.
В итоге, оптимальное решение - это абстракция ReaderAt, которая через системный вызов mincore проверяет, находится ли нужная страница уже в оперативной памяти. Если да, то используется быстрый mmap-путь, а если нет - то безопасный pread. При этом результаты mincore кэшируются в битовой карте на срок до минуты.
В статье еще разбирается целая куча самых разных тонкостей
https://kodikapusta.ru/news/1120-mmap-ili-pread
Поддержать проект на boosty и читать в MAX
Forwarded from Код и Капуста
Запилил ещё один видос. В этот раз рассказываю про программирование на Go под Playdate.
Пока только на ютубе: https://www.youtube.com/watch?v=TH1q-Yt8Jwc
Пока только на ютубе: https://www.youtube.com/watch?v=TH1q-Yt8Jwc
YouTube
Playdate и Go
Playdate — это компактная портативная игровая консоль от компании Panic и Teenage Engineering. У консоли черно-белый экран 2,7 дюйма без подсветки, необычное механическое управление крутилой кранком
В этом видео найчимся писать программы под playdate на…
В этом видео найчимся писать программы под playdate на…
Forwarded from Код и Капуста
Теперь про Go и Playdate доступен и на вквидео и на рутубе
вквидео https://vkvideo.ru/video-228916121_456239441
рутуб https://rutube.ru/video/338ceeb9741a5f53acf04b58b1ddff3d/
ну и на ютубе тоже посмотрите https://www.youtube.com/watch?v=TH1q-Yt8Jwc
Playdate — это компактная портативная игровая консоль от компании Panic и Teenage Engineering. У консоли черно-белый экран 2,7 дюйма без подсветки, необычное механическое управление крутилой кранком
В этом видео научимся писать программы под playdate на Go и напишем приложение для чтения новостей с сайта kodikapusta.ru
вквидео https://vkvideo.ru/video-228916121_456239441
рутуб https://rutube.ru/video/338ceeb9741a5f53acf04b58b1ddff3d/
ну и на ютубе тоже посмотрите https://www.youtube.com/watch?v=TH1q-Yt8Jwc
Playdate — это компактная портативная игровая консоль от компании Panic и Teenage Engineering. У консоли черно-белый экран 2,7 дюйма без подсветки, необычное механическое управление крутилой кранком
В этом видео научимся писать программы под playdate на Go и напишем приложение для чтения новостей с сайта kodikapusta.ru
VK Видео
Playdate и Go
Playdate — это компактная портативная игровая консоль от компании Panic и Teenage Engineering. У консоли черно-белый экран 2,7 дюйма без подсветки, необычное механическое управление с помощью крутилки-кранка Больше подробностей в статье https://kodikapus…
👎1🔥1😁1
Forwarded from Код и Капуста
OpenTelemetry в комптайме
#golang
Разрабы OpenTelemetry объявили о первом стабильном релизе Go Compile-Time Instrumentation (v1)
Новый инструмента otelc, который встраивает телеметрию в Go-бинарник на этапе компиляции через механизм -toolexec, без правок исходного кода и без отдельного кода в рантайме. В v1 поддерживаются net/http, database/sql, gRPC, Redis и метрики рантайма Go. Можно инструментировать кастомный код через специальные правила в конфиге.
Инструмент заменяет go build на otelc go build. Но это необязательно, можно просто настроить GOFLAGS с указанием toolexec, а значит все уже совместимо с вашим CI/CD
В будущем планируется реестр инструментаций, расширение покрытия библиотек и оптимизация
Лучшее использование toolexec, которое я видел
https://kodikapusta.ru/news/1127-opentelemetry-v-komptaime
Поддержать проект на boosty и читать в MAX
#golang
Разрабы OpenTelemetry объявили о первом стабильном релизе Go Compile-Time Instrumentation (v1)
Новый инструмента otelc, который встраивает телеметрию в Go-бинарник на этапе компиляции через механизм -toolexec, без правок исходного кода и без отдельного кода в рантайме. В v1 поддерживаются net/http, database/sql, gRPC, Redis и метрики рантайма Go. Можно инструментировать кастомный код через специальные правила в конфиге.
Инструмент заменяет go build на otelc go build. Но это необязательно, можно просто настроить GOFLAGS с указанием toolexec, а значит все уже совместимо с вашим CI/CD
В будущем планируется реестр инструментаций, расширение покрытия библиотек и оптимизация
Лучшее использование toolexec, которое я видел
https://kodikapusta.ru/news/1127-opentelemetry-v-komptaime
Поддержать проект на boosty и читать в MAX
🔥6❤1
Forwarded from Код и Капуста
Go конкурентность в C
#golang #c
Автор исследует, насколько близко можно воспроизвести конкурентную модель Go на чистом C с помощью только POSIX-потоков. Это делается для проекта Solod - строгого подмножества Go, транслируемого в C без рантайма и сборщика мусора.
Реализация построена на двух примитивах - pthread_mutex_t и pthread_cond_t. Поверх них сделаны мьютексы, condition-переменные, пул воркеров с кольцевым буфером и буферизированные/небуферизированные каналы с рандеву-передачей значений напрямую со стека отправителя. Но без зеленых тредов и своего планировщика
Бенчмарки показывают, что на крупных задачах пул pthreads уступает Go всего ~10%, а атомики и неподблокированные мьютексы даже быстрее, но как только поток паркуется в ядре, накладные расходы на wakeup-сисколлы дают проигрыш до 23 раз. Это, очевидно, плата за отсутствие отдельного планировщика и простоту кода в ~200 строк
https://kodikapusta.ru/news/1128-go-konkurentnost-v-c
Поддержать проект на boosty и читать в MAX
#golang #c
Автор исследует, насколько близко можно воспроизвести конкурентную модель Go на чистом C с помощью только POSIX-потоков. Это делается для проекта Solod - строгого подмножества Go, транслируемого в C без рантайма и сборщика мусора.
Реализация построена на двух примитивах - pthread_mutex_t и pthread_cond_t. Поверх них сделаны мьютексы, condition-переменные, пул воркеров с кольцевым буфером и буферизированные/небуферизированные каналы с рандеву-передачей значений напрямую со стека отправителя. Но без зеленых тредов и своего планировщика
Бенчмарки показывают, что на крупных задачах пул pthreads уступает Go всего ~10%, а атомики и неподблокированные мьютексы даже быстрее, но как только поток паркуется в ядре, накладные расходы на wakeup-сисколлы дают проигрыш до 23 раз. Это, очевидно, плата за отсутствие отдельного планировщика и простоту кода в ~200 строк
https://kodikapusta.ru/news/1128-go-konkurentnost-v-c
Поддержать проект на boosty и читать в MAX
🔥4
Forwarded from Код и Капуста
Убираем ограничения
#golang
Автор разбирает продвинутый прием устранения проверки границ в горячих путях Go
Когда компилятор не может доказать безопасность доступа к срезу, а программист может, на помощь приходит unsafe.Pointer с арифметикой указателей. Вместо
Кроме очевидного сокращения инструкций и ветвлений в хотпасе, вы еще и работу кеша процессора улучшаете. Меньше инструкций, меньше мисов
https://kodikapusta.ru/news/1129-ubiraem-ogranicheniia
Поддержать проект на boosty и читать в MAX
#golang
Автор разбирает продвинутый прием устранения проверки границ в горячих путях Go
Когда компилятор не может доказать безопасность доступа к срезу, а программист может, на помощь приходит unsafe.Pointer с арифметикой указателей. Вместо
binary.LittleEndian.Uint32(data[i:]) можно использовать *(*uint32)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i)), что устраняет все проверки границ и на реальном бенчмарке brotli-компрессора даёт прирост ~10%. У автора в статье довольно много таких хаковКроме очевидного сокращения инструкций и ветвлений в хотпасе, вы еще и работу кеша процессора улучшаете. Меньше инструкций, меньше мисов
https://kodikapusta.ru/news/1129-ubiraem-ogranicheniia
Поддержать проект на boosty и читать в MAX
👎3👍2
Forwarded from Код и Капуста
GALA
#golang #tools
GALA (Go Alternative LAnguage) - статически типизированный функциональный язык, транспилирующийся в Go, который приносит в экосистему Go sealed-типы с исчерпывающим паттерн матчиг, монадический стек, иммутабельные коллекции и do-нотацию с накоплением ошибок через Validated и конкурентным выполнением через Future. Уже даже есть примеры проектов на GALA
Кароче, ребята решили SCALA написать на Go
https://kodikapusta.ru/tools/24-gala
Поддержать проект на boosty и читать в MAX
#golang #tools
GALA (Go Alternative LAnguage) - статически типизированный функциональный язык, транспилирующийся в Go, который приносит в экосистему Go sealed-типы с исчерпывающим паттерн матчиг, монадический стек, иммутабельные коллекции и do-нотацию с накоплением ошибок через Validated и конкурентным выполнением через Future. Уже даже есть примеры проектов на GALA
Кароче, ребята решили SCALA написать на Go
https://kodikapusta.ru/tools/24-gala
Поддержать проект на boosty и читать в MAX
😁4
Forwarded from Код и Капуста
HTMX с Go
#golang
Автор детально описывает свои паттерны интеграции HTMX с Go. Почитайте, там много всего интересного.
Но мне весь это веб всё еще не нравится. Любой HTML - это в первую очередь ебля со стилями. Я хотел бы, чтобы уже сделали как во Flutter или Qt, чтобы было очевидно, как выравнивать и форматировать блоки. А не вот это всё
https://kodikapusta.ru/news/1135-htmx-s-go
Поддержать проект на boosty и читать в MAX
#golang
Автор детально описывает свои паттерны интеграции HTMX с Go. Почитайте, там много всего интересного.
Но мне весь это веб всё еще не нравится. Любой HTML - это в первую очередь ебля со стилями. Я хотел бы, чтобы уже сделали как во Flutter или Qt, чтобы было очевидно, как выравнивать и форматировать блоки. А не вот это всё
https://kodikapusta.ru/news/1135-htmx-s-go
Поддержать проект на boosty и читать в MAX
❤1👎1
Forwarded from Код и Капуста
687 ГБ аллокаций
#golang
Автор профилировал свою многопоточную реализацию Redis на Go и обнаружил, что одна строка кода
Проблема была в том, что LPUSH каждый раз создавал новый массив и копировал весь существующий список, давая O(n²) по аллокациям, тогда как RPUSH использовал штатную стратегию роста слайсов с амортизированным O(1).
Замена на deque с двумя индексами, растущий от середины в обе стороны, ускорила LPUSH в 33 раза, а аллокации упали с 715 ГБ до 27 ГБ
Нужно быть внимательным
https://kodikapusta.ru/news/1136-687-gb-allokatsii
Поддержать проект на boosty и читать в MAX
#golang
Автор профилировал свою многопоточную реализацию Redis на Go и обнаружил, что одна строка кода
s.kvList[k] = append(v[popped:], s.kvList[k]...) за время бенчмарка суммарно аллоцировала 687 ГБ памяти. Реально приложение держало в памяти лишь около 4,58 МБ. В чем прикол?Проблема была в том, что LPUSH каждый раз создавал новый массив и копировал весь существующий список, давая O(n²) по аллокациям, тогда как RPUSH использовал штатную стратегию роста слайсов с амортизированным O(1).
Замена на deque с двумя индексами, растущий от середины в обе стороны, ускорила LPUSH в 33 раза, а аллокации упали с 715 ГБ до 27 ГБ
Нужно быть внимательным
https://kodikapusta.ru/news/1136-687-gb-allokatsii
Поддержать проект на boosty и читать в MAX
❤10
Forwarded from Код и Капуста
Арены жалко
#golang
Go отказался от экспериментальных Memory Arenas - механизма, позволявшего выделять память крупными пулами в обход GC для снижения накладных расходов в высоконагруженных сценариях.
Автор считает это стратегической ошибкой. Формальной причиной стали проблемы безопасности, когда можно попытаться использовать память после ее освобождения. И еще никому не понравилась несовместимость с интерфейсами - пришлось бы добавлять аргумент *Arena в сигнатуры функций, и это раскололо бы экосистему на стандартный и arena-миры, подобно тому как context.Context когда-то "инфицировал" весь Go.
Но, по мнению автора, реальная опасность в том, что Go добровольно ограничил свой потолок производительности в момент, когда быстрые интерпретируемые языки догоняют его сверху, а системные языки вроде Rust и Zig становятся проще снизу. Go рискует остаться застывшим в "среднем" сегменте, став COBOLом облачной эпохи
https://kodikapusta.ru/news/1137-areny-zhalko
Поддержать проект на boosty и читать в MAX
#golang
Go отказался от экспериментальных Memory Arenas - механизма, позволявшего выделять память крупными пулами в обход GC для снижения накладных расходов в высоконагруженных сценариях.
Автор считает это стратегической ошибкой. Формальной причиной стали проблемы безопасности, когда можно попытаться использовать память после ее освобождения. И еще никому не понравилась несовместимость с интерфейсами - пришлось бы добавлять аргумент *Arena в сигнатуры функций, и это раскололо бы экосистему на стандартный и arena-миры, подобно тому как context.Context когда-то "инфицировал" весь Go.
Но, по мнению автора, реальная опасность в том, что Go добровольно ограничил свой потолок производительности в момент, когда быстрые интерпретируемые языки догоняют его сверху, а системные языки вроде Rust и Zig становятся проще снизу. Go рискует остаться застывшим в "среднем" сегменте, став COBOLом облачной эпохи
https://kodikapusta.ru/news/1137-areny-zhalko
Поддержать проект на boosty и читать в MAX
🤔4👍2👎2❤1