Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go 
для разработчиков на 
C++ 
Слава Бахмутов - старший разработчик 
C++ party Новосибирск, 26.09.2014
Структура доклада 
1. Пропаганда 
1. История Go и описание языка 
2. Особенности нашей разработки 
3. Выбор, внедрение и выводы 
2. Внутренности 
A. Память 
B. Функции и escape analysis 
C. Go рутины 
D. Планировщик 
E. Стек 
3
Пропаганда 
4 
1. История Go и описание языка 
2. Особенности нашей разработки 
3. Выбор, внедрение и выводы
История Go. Начало. 
Разработан и поддерживается Google 
2007 — начало разработки 
2009 — публичный релиз 
2012 — go 1.0 
2014 — go 1.3. ОС: Linux, Mac OS X, 
FreeBSD, NetBSD, OpenBSD, Plan 9 и 
Microsoft Windows. Платформы: i386, amd64 и 
ARM 
2015 — go 1.4 поддержка Android?* 
5 
* http://bit.ly/go-android 
Кен То́мпсон 
Роб Пайк
История Go. Развитие. 
6 
https://www.openhub.net/languages/compare
История Go. Развитие. 
7 
https://www.openhub.net/languages/compare
История Go. Проекты. 
8 
Gogs 
Github репозитории, написанные на Go
История Go. Сообщество. 
9 
Группа Golang Russian
История Go. Бизнес. 
10 
Список компаний
Описание языка. Кратко. 
1. Очень простой. 
2. Компилируемый, со строгой типизацией. 
3. Со сборкой мусора 
4. Лёгкие процессы - Go рутины. 
5. Нет дженериков, наследования, переопределения методов, 
pointer arithmetic. 
6. Богатая стандартная библиотека, но не шлак. 
7. Большой набор инструментов для разработки (запуск тестов с 
[покрытием], форматирование кода, кросскомпиляция, отладка, 
поиск гонок, профилирование и т.д.) 
8. Разработан для больших команд и высокой нагрузки (со вкусом 
Google) 
11
Особенности нашей разработки. 
12 
Python 
C++ 
~500 RPS 
>5000 RPS
Проблемы 
- медленная разработка 
- трудно писать юнит 
тесты 
- а никто и не пишет =( 
13 
С++ 
Python 
- медленная работа 
- юнит тесты для 
проверки типов 
- жадный до ресурсов 
- лапша калбеков 
- зависимости
В поисках нового. 
14
Внедрение Go в Cocaine. 
Написали фреймворк за выходные* 
Приложения в облаке — обычные HttpHandler 
Приложения запускаются и без Cocaine 
15 * http://bit.ly/cocaine-go
Выводы. Плюсы. 
16 
Тесты 
Go рутины 
Простота языка 
Исследование проблем, улов утечек 
Мало потребляет, много обрабатывает 
Питонщики с радостью переходят на Go 
Нет зависимостей 
Быстрая компиляция
Выводы. Тесты. 
17 
Всё включено: 
go test -bench 
go test -bench -cpu=1,2,4 
go test -benchmem 
go test -cpuprofile 
go test -memprofile 
go test -blockprofile
Выводы. Тесты. 
18 
+ мощность покрытия
Выводы. Тесты 
19 
BDD, TDD и другие
Выводы. Профайлинг. 
20 
Профайлер горутин 
Трейсер GC 
Трейсер планировщика 
Трейсер аллокатора памяти 
Статистика аллокатора памяти 
Дамп кучи
Выводы. Профайлинг. 
21
Выводы. Профайлинг. 
22
Выводы. Races. 
23
Выводы. Производительность. 
24 
Python C++ 
Регулярки уже починили
Выводы. Производительность. 
25 
С++ 
Тесты http 
доступа к Elliptics
Выводы. Производительность. 
26 
Go 1.3 GC off 
Тесты http 
доступа к Elliptics
Выводы. Производительность. 
27 
Go 1.3 GC on 
Тесты http 
доступа к Elliptics
Выводы. Память. 
28 
Много данных 
В среднем 
Много клиентских http запросов (~1000rps)
Выводы. Минусы. Моё мнение. 
29 
Generics - но не так критично 
Работа с ошибками 
Неочевидность некоторых вещей 
Проблемы в библиотеках 
Часть вещей приходится писать самим 
Плюсовики переходят на Go с трудом
Выводы. Минусы плюсовиков. 
Дорогие вызовы сишных расширений 
Писать расширения для С++ - задолбешься и вызовешь сОтОну 
Нет возможностей тонкого управления GC 
Недооптимизированный оптимизатор 
Встроенные range, len, cap, make итд только для builtin типов 
Нет человеческих исключений. Протаскивание ошибок по стеку 
сильно утомляет 
Зато есть странные паники и затычка в виде defer. 
Определение области видимости по регистру первой буквы. Хорошо 
еще блоки не пробельными символами определяются. 
! 
30
Выводы. Плюсы плюсовиков. 
Интерфейсы зашибись, для проектирования и тестирования. 
Асинхронщина легка, как утренний ветер. 
К тому же HTTP библиотека хорошая, плюсы похвастать этим не 
могут. 
Тесты - важная часть программирования. То что они "в пакете" - это 
ценно. 
Удобно устанавливать пакеты через go get 
Хорошее и удобное low-level crypto api 
31
Выводы. Результаты. 
32 
В 2 раза медленнее C++ и в 8-15 раз быстрее python* 
В ~30 раз меньше потребление памяти чем python* 
Нагрузка на кластер уменьшилась на 70 % 
Ручки работают уже год и не единого разрыва 
* на наших задачах
Внутренности 
33 
A. Память 
B. Функции и escape analysis 
C. Go рутины 
D. Планировщик 
E. Стек
Память. 
34 
Go - 4 байта 
Python - 24 байта 
Java - 4 байта Java - 16/24 байта (32/64) 
Структуры с поправкой на выравнивание
Память. 
35
Вызов функций 
1.Создаётся новый фрейм стека и записывается 
информация о вызывающей функции. 
2.Все регистры, которые могут быть перезаписаны - 
сохраняются. 
3.Контекст выполнения переключается на адрес новой 
функции 
36 
Достаточно дорого
Вызов функций. Inlining 
1.Почти все небольшие функции встраиваются. 
2.Даже между разными пакетами. В том числе и из 
стандартной библиотеки (учитывает это). 
3.Увеличивается размер исполняемого файла. 
4.Уменьшаются накладные расходы 
5.Ничего нового, так делают почти все. 
6.Приводит к дополнительным оптимизациям. 
37
Вызов функций. Inlining 
38 
Оптимизируется мёртвый код 
Помогает решить: стек или куча
Escape analysis 
1.Go сам решает, где выделяется память 
2.Определяет, выходят ли указатели на значение за функцию или нет. 
3.Если нет, то данные спокойно располагаются на стеке 
4.Данные на стеке удаляются после выхода из функции и 
освобождения стека все скопом. 
5.Нет повода беспокоить сборщик мусора 
! 
39
Escape analysis. Пример 1 
40 
1.Значение numbers расположится на стеке 
2.Функция ничего не размещает в куче 
3.Сборщик мусора не у дел
Escape analysis. Пример 2 
41 
1.Функция Center встроится в CenterCursor 
2.Cursor не покидает функцию и будет 
располагаться на стеке
Escape analysis. Дебаг 
42
Go рутины. Причины. 
1.Системные треды тяжелые 
2.Избыточная функциональность. 
3.При сборке мусора нужно консистентное состояние 
4.Хочется модель N:M 
43
Go рутины. 
1.Кооперативная многозадачность 
2.Переключение между Go рутинами в точно определённых моментах 
3.Компилятор знает, какие регистры используются и сохраняет их 
автоматически 
4.Выделяется 4 кб памяти на стек (дальше меньше) 
5.Выделение памяти только при запуске. 
44
Go рутины. Переключение 
1.Работа с каналами 
2.Блокирующие системные вызовы 
3.Сборка мусора 
4.Вызов функций (не инлайн) 
5.netpoller (epoll, kqueue ..) 
6.Добровольно runtime.gosched 
7.ещё 
45
Go рутины. Переключение 
46
Go рутины. Планировщик. 
47 
Как это было
Go рутины. Планировщик. 
48 
M - системный тред 
P - процесс (контекст) 
G - Go рутина 
Как стало
Go рутины. Планировщик. 
49
Go рутины. Планировщик. 
50 
M1 берётся из пула или создаётся
Go рутины. Планировщик. 
51 
Балансировка Go рутин
Go рутины. Планировщик. 
52 
1.Пытаемся распределять Go рутины, в зависимости друг от друга 
2.Go рутины запускаются на горячем кеше 
3.Одна глобальная очередь и локальные на каждом P 
4.Оптимизация работы с каналами (отдельная большая тема)
Стек 
53 
Надо сразу выделить побольше стека
Стек в Go рутинах 
54 
1.Нет guard pages 
2.Размер стека очень маленький (4кб) 
3.Стек растёт если нужно
Стек в Go рутинах 
55
Стек в Go рутинах 
56 
Hot-split problem
Стек в Go рутинах 
57
Garbage collector. Планы 
1.Гибридный STW/CGC, tricolor mark and sweep 
2.Quality of Service 10/50 ms 
3.Огромное пространство для улучшения 
4.Отдельная большая тема 
! 
58
Источники 
1.Analysis of the Go runtime scheduler (Columbia University) 
2.Morsing’s Blog 
3.The Go Programming Language Blog 
4.Dmitry Vyukov (blog, answers and proposals) 
5.Dave Chaney 
6.Golang groups: nuts and devs and russian 
59
Спасибо за внимание 
60 
twitter: @m0sth8 
email: m0sth8@yandex-team.ru 
доклад: http://bit.ly/go-doklad2

More Related Content

Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов

  • 2. Плюсы и минусы Go для разработчиков на C++ Слава Бахмутов - старший разработчик C++ party Новосибирск, 26.09.2014
  • 3. Структура доклада 1. Пропаганда 1. История Go и описание языка 2. Особенности нашей разработки 3. Выбор, внедрение и выводы 2. Внутренности A. Память B. Функции и escape analysis C. Go рутины D. Планировщик E. Стек 3
  • 4. Пропаганда 4 1. История Go и описание языка 2. Особенности нашей разработки 3. Выбор, внедрение и выводы
  • 5. История Go. Начало. Разработан и поддерживается Google 2007 — начало разработки 2009 — публичный релиз 2012 — go 1.0 2014 — go 1.3. ОС: Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD, Plan 9 и Microsoft Windows. Платформы: i386, amd64 и ARM 2015 — go 1.4 поддержка Android?* 5 * http://bit.ly/go-android Кен То́мпсон Роб Пайк
  • 6. История Go. Развитие. 6 https://www.openhub.net/languages/compare
  • 7. История Go. Развитие. 7 https://www.openhub.net/languages/compare
  • 8. История Go. Проекты. 8 Gogs Github репозитории, написанные на Go
  • 9. История Go. Сообщество. 9 Группа Golang Russian
  • 10. История Go. Бизнес. 10 Список компаний
  • 11. Описание языка. Кратко. 1. Очень простой. 2. Компилируемый, со строгой типизацией. 3. Со сборкой мусора 4. Лёгкие процессы - Go рутины. 5. Нет дженериков, наследования, переопределения методов, pointer arithmetic. 6. Богатая стандартная библиотека, но не шлак. 7. Большой набор инструментов для разработки (запуск тестов с [покрытием], форматирование кода, кросскомпиляция, отладка, поиск гонок, профилирование и т.д.) 8. Разработан для больших команд и высокой нагрузки (со вкусом Google) 11
  • 13. Проблемы - медленная разработка - трудно писать юнит тесты - а никто и не пишет =( 13 С++ Python - медленная работа - юнит тесты для проверки типов - жадный до ресурсов - лапша калбеков - зависимости
  • 15. Внедрение Go в Cocaine. Написали фреймворк за выходные* Приложения в облаке — обычные HttpHandler Приложения запускаются и без Cocaine 15 * http://bit.ly/cocaine-go
  • 16. Выводы. Плюсы. 16 Тесты Go рутины Простота языка Исследование проблем, улов утечек Мало потребляет, много обрабатывает Питонщики с радостью переходят на Go Нет зависимостей Быстрая компиляция
  • 17. Выводы. Тесты. 17 Всё включено: go test -bench go test -bench -cpu=1,2,4 go test -benchmem go test -cpuprofile go test -memprofile go test -blockprofile
  • 18. Выводы. Тесты. 18 + мощность покрытия
  • 19. Выводы. Тесты 19 BDD, TDD и другие
  • 20. Выводы. Профайлинг. 20 Профайлер горутин Трейсер GC Трейсер планировщика Трейсер аллокатора памяти Статистика аллокатора памяти Дамп кучи
  • 24. Выводы. Производительность. 24 Python C++ Регулярки уже починили
  • 25. Выводы. Производительность. 25 С++ Тесты http доступа к Elliptics
  • 26. Выводы. Производительность. 26 Go 1.3 GC off Тесты http доступа к Elliptics
  • 27. Выводы. Производительность. 27 Go 1.3 GC on Тесты http доступа к Elliptics
  • 28. Выводы. Память. 28 Много данных В среднем Много клиентских http запросов (~1000rps)
  • 29. Выводы. Минусы. Моё мнение. 29 Generics - но не так критично Работа с ошибками Неочевидность некоторых вещей Проблемы в библиотеках Часть вещей приходится писать самим Плюсовики переходят на Go с трудом
  • 30. Выводы. Минусы плюсовиков. Дорогие вызовы сишных расширений Писать расширения для С++ - задолбешься и вызовешь сОтОну Нет возможностей тонкого управления GC Недооптимизированный оптимизатор Встроенные range, len, cap, make итд только для builtin типов Нет человеческих исключений. Протаскивание ошибок по стеку сильно утомляет Зато есть странные паники и затычка в виде defer. Определение области видимости по регистру первой буквы. Хорошо еще блоки не пробельными символами определяются. ! 30
  • 31. Выводы. Плюсы плюсовиков. Интерфейсы зашибись, для проектирования и тестирования. Асинхронщина легка, как утренний ветер. К тому же HTTP библиотека хорошая, плюсы похвастать этим не могут. Тесты - важная часть программирования. То что они "в пакете" - это ценно. Удобно устанавливать пакеты через go get Хорошее и удобное low-level crypto api 31
  • 32. Выводы. Результаты. 32 В 2 раза медленнее C++ и в 8-15 раз быстрее python* В ~30 раз меньше потребление памяти чем python* Нагрузка на кластер уменьшилась на 70 % Ручки работают уже год и не единого разрыва * на наших задачах
  • 33. Внутренности 33 A. Память B. Функции и escape analysis C. Go рутины D. Планировщик E. Стек
  • 34. Память. 34 Go - 4 байта Python - 24 байта Java - 4 байта Java - 16/24 байта (32/64) Структуры с поправкой на выравнивание
  • 36. Вызов функций 1.Создаётся новый фрейм стека и записывается информация о вызывающей функции. 2.Все регистры, которые могут быть перезаписаны - сохраняются. 3.Контекст выполнения переключается на адрес новой функции 36 Достаточно дорого
  • 37. Вызов функций. Inlining 1.Почти все небольшие функции встраиваются. 2.Даже между разными пакетами. В том числе и из стандартной библиотеки (учитывает это). 3.Увеличивается размер исполняемого файла. 4.Уменьшаются накладные расходы 5.Ничего нового, так делают почти все. 6.Приводит к дополнительным оптимизациям. 37
  • 38. Вызов функций. Inlining 38 Оптимизируется мёртвый код Помогает решить: стек или куча
  • 39. Escape analysis 1.Go сам решает, где выделяется память 2.Определяет, выходят ли указатели на значение за функцию или нет. 3.Если нет, то данные спокойно располагаются на стеке 4.Данные на стеке удаляются после выхода из функции и освобождения стека все скопом. 5.Нет повода беспокоить сборщик мусора ! 39
  • 40. Escape analysis. Пример 1 40 1.Значение numbers расположится на стеке 2.Функция ничего не размещает в куче 3.Сборщик мусора не у дел
  • 41. Escape analysis. Пример 2 41 1.Функция Center встроится в CenterCursor 2.Cursor не покидает функцию и будет располагаться на стеке
  • 43. Go рутины. Причины. 1.Системные треды тяжелые 2.Избыточная функциональность. 3.При сборке мусора нужно консистентное состояние 4.Хочется модель N:M 43
  • 44. Go рутины. 1.Кооперативная многозадачность 2.Переключение между Go рутинами в точно определённых моментах 3.Компилятор знает, какие регистры используются и сохраняет их автоматически 4.Выделяется 4 кб памяти на стек (дальше меньше) 5.Выделение памяти только при запуске. 44
  • 45. Go рутины. Переключение 1.Работа с каналами 2.Блокирующие системные вызовы 3.Сборка мусора 4.Вызов функций (не инлайн) 5.netpoller (epoll, kqueue ..) 6.Добровольно runtime.gosched 7.ещё 45
  • 47. Go рутины. Планировщик. 47 Как это было
  • 48. Go рутины. Планировщик. 48 M - системный тред P - процесс (контекст) G - Go рутина Как стало
  • 50. Go рутины. Планировщик. 50 M1 берётся из пула или создаётся
  • 51. Go рутины. Планировщик. 51 Балансировка Go рутин
  • 52. Go рутины. Планировщик. 52 1.Пытаемся распределять Go рутины, в зависимости друг от друга 2.Go рутины запускаются на горячем кеше 3.Одна глобальная очередь и локальные на каждом P 4.Оптимизация работы с каналами (отдельная большая тема)
  • 53. Стек 53 Надо сразу выделить побольше стека
  • 54. Стек в Go рутинах 54 1.Нет guard pages 2.Размер стека очень маленький (4кб) 3.Стек растёт если нужно
  • 55. Стек в Go рутинах 55
  • 56. Стек в Go рутинах 56 Hot-split problem
  • 57. Стек в Go рутинах 57
  • 58. Garbage collector. Планы 1.Гибридный STW/CGC, tricolor mark and sweep 2.Quality of Service 10/50 ms 3.Огромное пространство для улучшения 4.Отдельная большая тема ! 58
  • 59. Источники 1.Analysis of the Go runtime scheduler (Columbia University) 2.Morsing’s Blog 3.The Go Programming Language Blog 4.Dmitry Vyukov (blog, answers and proposals) 5.Dave Chaney 6.Golang groups: nuts and devs and russian 59
  • 60. Спасибо за внимание 60 twitter: @m0sth8 email: m0sth8@yandex-team.ru доклад: http://bit.ly/go-doklad2