The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"Релиз языка программирования Go 1.14"
Отправлено anonymous, 08-Мрт-20 14:46 
По-хорошему надо написать benchmark-тесты, найти узкие места и устранить. И обычно, когда пишут на Go, стараются в main-е держать лишь парсер флагов и запускатель когда и другого пакета. Таким образом легко становится делать тесты и разбираться почему что-то медленно работает.

Если это не очень актуально (как я понял), то, конечно же, лень тратить время на это. Поэтому давайте посмотрим хотя бы быстрым взглядом поверхностно (извиняюсь за низкое качество анализа):

1. Вы каждый раз выделаете огромный буфер:
buf := make([]byte, BUF_LEN)

Если убрать `go` от `serve`, то можно было бы один раз выделить этот буфер (просто вне `for`-а) и постоянно его использовать. Если `go` нужен. то можно постараться либо изменить serve (перенести функционал), чтобы ему не нужен был этот буфер, либо в крайнем случае хотя бы просто применить `sync.Pool` для переиспользования буферов. По факту в отдельной рутине (`go serve`) достаточно было оставить только ту часть, что с syscall-ами, ибо вычислительная часть занимает сильно меньше, что позволило бы сделать один статический буфер (и избежать даже `sync.Pool`).

Есть ощущение, что именно эта строчка и портит вам всю статистику.

2. Что такое `daemon`? Не вижу его в import-ах.

3.
            ipv4 = append(ipv4, fmt.Sprintf("%b %s", (head>>1), ip.String()))
...
    hostname = fmt.Sprintf("%s", buf[pointer+1:length-4-16])
...
    report := fmt.Sprintf("addr=%s\nhost=%s\n", addr.String(), hostname)
    if overhead {
        report += "overhead\n"
    }
... и т.п.

Это всё тоже в некоторых случаях нехило давит и на CPU и на GC. Опять же, sync.Pool + strings.Builder (вместо Sprintf).

Кроме того, преобразование []byte в string делает копию (давит и на CPU и на GC). Вы могли вообще без string тут обойтись (см. bytes.Builder, вместо strings.Builder).

То есть да, Sprintf удобен, но когда пишешь именно тот кусочек кода, где действительно важна производительность, то лучше избегать его использования.

---

В целом, если вам будет действительно важно что-то прооптимизировать на Go, то я буду рад разочек помочь. Если вам важно прооптимизировать именно эту программу, то с вашей стороны я бы попросил написать unit/integration тест для той части кода, что мы хотим оптимизировать. А я со своей стороны пообещаю добиться производительности близкой к Сишной без особых костылей.

Сделать unit/integration тест очень несложно: просто превратите listen_udp в функцию, которая принимает этот `pc` извне аргументом типа net.Conn и напишите тест, который вызывает эту функцию, посылает туда хотя бы парочку разных пакетов и проверяет правильность результата.

Я добавлю benchmark тест. Сделаю `go test ./ -bench=. -cpuprofile /tmp/cpu.pprof -memprofile /tmp/mem.pprof`, глянем на реально слабые места этой программы и исправим ;)

https://golang.org/pkg/testing/

 

Ваше сообщение
Имя*:
EMail:
Для отправки ответов на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
  Введите код, изображенный на картинке: КОД
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру