Почему с быстрее python
Перейти к содержимому

Почему с быстрее python

  • автор:

Python избавился от недостатка, над которым смеялись все программисты. Его научили работать со скоростью С и С++

Python получил сверхбыстрый компилятор. Производительность скомпилированных им программ оказалась в 10-100 раз быстрее в сравнении с приложениями на выходе традиционного интерпретатора CPython. Теперь по этому параметру Python ничуть не уступает, а в некоторых случаях даже превосходит С и C++, своих главных конкурентов среди языков программирования.

Python ускорился

Язык программирования Python, самый популярный и очень востребованный в мире, в одночасье стал в несколько раз лучше благодаря стараниям экспертов стартапа Exaloop и Массачусетского технологического института (MIT). Они создали компилятор Codon, существенно повышающий производительность скомпилированных приложений на фоне их аналогов, вышедших из-под стандартных интерпретаторов. По скорости работы они едва ли не быстрее программ на С и C++, пишет The Register.

Низкая производительность программ – то, за что Python, при всей простоте его освоения, ругают чаще всего. И нередко в этом плане его сравнивают именно с С и C++, притом не в его пользу. Codon устраняет это неравенство – по словам разработчиков, он способен генерировать на выходе чистый машинный код без привязки к среде выполнения Python Runtime.

Разработчики уверяют, что в сравнении с обычными интерпретаторами для Python новый Codon обеспечивает ПО в 10-100 раз более высокую производительность. В данном случае идет сравнение с интерпретатором CPython при в однопоточном режиме работы. «Производительность Codon обычно соответствует (а иногда и лучше) производительности компиляторов C/C++», – утверждают они.

Все бесплатно, но не совсем

Проект Codon распространяется по лицензии Business Source License (BSL), то есть по умолчанию все его компоненты доступны бесплатно при соблюдении ряда условий эксплуатации. Все без исключения файлы, необходимые для работы Codon, размещены в профиле стартапа Exaloop на GitHub (принадлежит Microsoft). В комплект входят компилятор, среда выполнения (runtime) для исполняемых файлов и отдельная библиотека функций на замену штатным библиотечным вызовам на Python.

pyn600.jpg

Python получил еще одно неоспоримое преимущество

Что немаловажно, исходные тексты самого компилятора, библиотеки и runtime написаны вовсе не на Python, как многие, вероятно, ожидали. Авторы использовали C++.

Ограничения, накладываемые лицензией BSL на бесплатное использование распространяемого под ней ПО, всегда имеют срок действия. В случае с Codon они продлялся до 1 ноября 2025 г., после чего весь проект будет переведен на лицензию Apache 2.0. А пока Codon распространяется под BSL, его код можно копировать и модифицировать, если в дальнейшем он не будет использоваться в коммерческих целях.

Плюсов без минусов не бывает

Codon разрабатывается как фреймворк для создания высокопроизводительных предметно-ориентированных языков (DSL) в Python. DSL — это языки, ориентированные на конкретную цель, в отличие от языка программирования общего назначения, которым относятся, например, Python или C. Примеры DSL – это CSS и SQL.

У истоков проекта стоят создатели Python-подобного языка программирования Seq, который и лежит в его основе. Авторы Codon позиционируют его как наследника Seq.

Дмитрий Рубин, Naumen: За 20 лет мы создали целую экосистему в области управления ИТ
Цифровизация

К недостаткам Codon эксперты The Register относят в первую очередь выбор разработчиками лицензии BSL с ее ограничениями, и необходимость ждать два с половиной года до перехода на Apache 2.0. Также они упомянули отсутствие поддержки некоторых модулей Python. Например, компилятор пока не поддерживает функции динамической обработки типов, плюс для целых чисел в нем используется только 64-битный тип int. В CPython таких ограничений нет.

Плюсы Codon – это очень высокая производительность при однопоточном выполнении. Компилятор также снабжен возможностью работы в многопоточном режиме.

Почему именно C++

Python – это самый популярный язык программирования в мире, согласно рейтингу Tiobe. На первое место в нем он вырвался лишь в октябре 2021 г., хотя существует Python c середины 1980-х годов. Его популярность стремительно растет лишь в последние несколько лет, тогда как другие представители топ-3 Tiobe находятся на вершине этого рейтинга годами.

Основной конкурент Python – это С, с компилятором для которого авторы Codon сравнили свое детище в первую очередь. До октября 2021 г. именно он был первым в рейтинге Tiobe. В декабре 2022 г. в тройку лидеров, сместив Java, вошел C++ – еще один конкурент Python. Скорость компиляции всегда была их неоспоримым преимуществом перед Python, которого, благодаря Codon, больше нет.

Почему С++ быстрее многих языков программирования?

Достаточно интересно полностью понять, почему С++ настолько быстр по сравнению с условным Kotlin, Java или C#. Вопрос: Расскажите пожалуйста в деталях, почему именно так) Предполагаю, что это благодаря достаточно гибкой работой с памятью, но кажется, что сильно заблуждаюсь)

Отслеживать
задан 6 мая 2023 в 14:41
118 2 2 серебряных знака 15 15 бронзовых знаков

Потому что он компилируется в машинный код, который выполняется процессором напрямую, а не через виртуальную машину какую-нибудь

6 мая 2023 в 14:43
6 мая 2023 в 14:53
@aleksandrbarakin тут вопрос не про Python
6 мая 2023 в 14:53
@andreymal, какая разница? ответы там есть и они полностью покрывают смысл данного вопроса.
6 мая 2023 в 14:54

@aleksandrbarakin целых три принципиальных разницы: в питоне (подразумеваю CPython) есть GIL, нет статической типизации и нет JIT-компиляации — а в Java и C# всё ровно наоборот

6 мая 2023 в 14:56

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

Во, я наверное хорошо смогу ответить, так как являюсь специалистом в C# и .NET

Но перед тем как вникать в суть, запомните основное правило: тормозит не язык, на котором вы написали код или среда выполнения, тормозит сам код, который вы написали.

И главная проблема плохого тормозящего кода в таких средах со сборщиком мусора, как .NET и Java, это отсутствие экспертизы в области поведения той самой машины управления памятью. Хочешь создать 200кк массивов для выполнения задачи — легко, код прост. Просто спавни объекты и ни о чем не думай, а сборщик мусора разберется.

В таких средах, где нет встроенного управления памятью, и надо его писать по большей части самому, приходится разбираться с этим до того как код дописать, потому что иначе будут утечки и прочие неприятности. Когда учишь С++, изначально познаешь базовые тонкости работы с памятью, а многие новички сразу начинают различать malloc и calloc , и осознавать, что выделение высвобождение памяти не бесплатно по времени и требует работы, переиспользуют память и т.д.

Чтобы научиться контролю аллокаций в средах типа .NET, требуется сначала написать много тормознутого кода, и наконец-то встретиться с проблемой низкой производительности или перерасхода памяти лицом к лицу. То есть вникание в управление памятью и суть работы сборщика происходит гораздо позднее. Поэтому при одинаковом объеме обучающих материалов, специалист по C++ узнает про нюансы производительности раньше, чем специалист по C#. И это нормально, это специфика среды, в которой работает код.

Поэтому вопрос «что быстрее, С++ или C#/Java» изначально не имеет смысла. Даже если столкнуть лбами двух супермегаэкспертов C++ и C# — неизвестно, чей код будет быстрее. Напишешь на C++ код, потом начнешь тестировать, на одном сервере победишь C#, на другом в другой архитектуре — проиграешь. Ну потому что JIT во время компиляции знает все тонкости процессора, выполняющего код, а компилятор C++ — не знает, он знает только архитектуру. Есть еще PGO (Profile-Guided Optimization) в CLR (Common Language Runtime/.NET) — великолепная шутка, которая может перекомпилировать с сильными оптимизациями код уже запущенного приложения в зависимости от интенсивности использования некоторых методов в коде (речь про последние версии .NET, но раньше ситуация была хуже). В C++ такого либо нет, либо оно достигается значительно тяжелее, чем в среде с JIT. И еще миллионы нюансов, которые никак не ответят на ваш вопрос однозначно.

И здесь можно повторить вывод, который написан жирным шрифтом выше, в самом начале. А утверждение «С++ быстрее многих языков программирования» по факту не соответствует действительности. Я могу на C# написать код, который будет например применять фильтр к Full HD картинке 2 секунды, а могу потом переписать его так, что станет потом 4мс, а качество машинного кода, который выдает JIT, будет не сильно хуже, чем генерит gcc/clang. Не забывайте, что компиляция байт-кода (или CIL) производится машиной в целом однократно, а затем уже работает только скомпилированная версия. Например вызываете какой-то метод 1000 раз, а компилироваться он будет только однажды. JIT — это не интерпритатор байт-кода, а компилятор.

Что быстрее, Bash или Python?

ПРивет, посоны. С коллегой тут закусился, что быстрее работает? Я топил за питон, так как начитался недавних пресс-релизов об ускорении аж до 60%. Но других аргументов то у меня собственно и нет. Поэтому пришёл сюда, чтобы набраться мудрости и завтра ковровым аргументометанием принудить его к миру.

SpaceRanger ★★
21.11.22 07:35:14 MSK
1 2 3 →

Зависит от задачи. Если вызывать сторонние программы в основном, то Bash может быть быстрее за счёт меньшего времени непосредственно запуска скрипта (в самом начале). В большинстве остальных задач Python будет быстрее, и надо уже сравнивать насколько.

CrX ★★★
( 21.11.22 07:37:15 MSK )

alex1101 ☆
( 21.11.22 07:38:41 MSK )
Ответ на: комментарий от alex1101 21.11.22 07:38:41 MSK

да это то понятно. Я тут, кстати, перед завтраком ядро на нём переписал

SpaceRanger ★★
( 21.11.22 07:42:56 MSK ) автор топика

Ну замеряйте. Прогоните пару задач.

chenbr0
( 21.11.22 07:45:13 MSK )

Что быстрее, молоток или плоскогубцы?

shell-script ★★★★★
( 21.11.22 07:49:11 MSK )
Ответ на: комментарий от shell-script 21.11.22 07:49:11 MSK

Молоток. У плоскогубцев аэродинамика слабовата

saibogo ★★★★
( 21.11.22 07:55:07 MSK )
Ответ на: комментарий от saibogo 21.11.22 07:55:07 MSK

А если нужно не забивать гвоздь, а проволоку согнуть особым манером?

shell-script ★★★★★
( 21.11.22 08:00:15 MSK )
Ответ на: комментарий от saibogo 21.11.22 07:55:07 MSK

hobbit ★★★★★
( 21.11.22 08:38:41 MSK )

Прочтение темы вызывает острое желание начать писать скриптуху на c++ 🙂 Ибо нефиг.

hobbit ★★★★★
( 21.11.22 08:39:45 MSK )
Последнее исправление: hobbit 21.11.22 08:40:04 MSK (всего исправлений: 1)

Баш – это клей для очень быстрых программ на Си. В зависимости от задачи он может быть как ОЧЕНЬ быстрее, так и очень медленнее.

Im_not_a_robot ★★★★★
( 21.11.22 08:45:41 MSK )
Ответ на: комментарий от shell-script 21.11.22 08:00:15 MSK

А если нужно не забивать гвоздь, а проволоку согнуть особым манером?

Если сгибать под прямым углом, пара ударов молотком быстрее, чем возиться с плоскогубцами. Но в этом случае молоток требует большего мастерства. Про КРУГЛОгубцы речь не шла 🙂

question4 ★★★★★
( 21.11.22 09:05:08 MSK )
Ответ на: комментарий от hobbit 21.11.22 08:39:45 MSK

может конкурс запилить?

Neresar ★★
( 21.11.22 09:05:22 MSK )

Баш хоть вызывается моментально, питон пока запустится можно чай заварить.

voltmod ★★
( 21.11.22 09:46:19 MSK )
Ответ на: комментарий от voltmod 21.11.22 09:46:19 MSK

А если в баш-скрипте запустить питон, то можно заварить чай, пока запускается баш? 🙂

shell-script ★★★★★
( 21.11.22 09:48:05 MSK )
Ответ на: комментарий от question4 21.11.22 09:05:08 MSK

Ты просто не умеешь пользоваться плоскогубцами. Ну или я молотком. 🙂

shell-script ★★★★★
( 21.11.22 09:48:58 MSK )

Быстрее всего мысль человеческая. Хороший алгоритм на баше/питоне быстрее плозого алгоритма на плюсах.

AntonI ★★★★
( 21.11.22 10:08:03 MSK )
Ответ на: комментарий от shell-script 21.11.22 07:49:11 MSK

Шуруп забитый молотком держит лучше чем гвоздь закрученный отверткой. А молотковая резьба вообще самое прочное соединение.

AntonI ★★★★
( 21.11.22 10:09:16 MSK )

Баш написан на си => баш быстрее.

untitl3d ★
( 21.11.22 10:20:34 MSK )
Ответ на: комментарий от voltmod 21.11.22 09:46:19 MSK

За 0.185 сек. ты вряд ли заваришь чай, но вот проглотить таблетку теоретически успеешь.

thesis ★★★★★
( 21.11.22 10:29:23 MSK )

Ну как бы. Числа складывать питон явно быстрее будет. Инициализироваться и вызывать другие программы баш. Какие ваши бенчмарки?

Aswed ★★★★★
( 21.11.22 10:34:10 MSK )
Ответ на: комментарий от untitl3d 21.11.22 10:20:34 MSK

[cppmm@damned compare]$ time ./c-world Hello, World! real 0m1,002s user 0m0,002s sys 0m0,000s [cppmm@damned compare]$ time ./python-world.py Hello, World! real 0m0,051s user 0m0,047s sys 0m0,003s 

shell-script ★★★★★
( 21.11.22 10:43:55 MSK )
Ответ на: комментарий от shell-script 21.11.22 10:43:55 MSK

А Python какой версии?

th3m3 ★★★★★
( 21.11.22 11:15:05 MSK )

Я как-то делал инвентаризацию сети (состоящей на 99,9% из Cisco).
Программа должна была лазать по железкам по SNMP, собирать инфу и
рекурсивно обходить сегмент сети на основании таблички CDP.
Так вот, прототип я наваял на bash+snmpwalk/snmpget и так далее.
Работало это миллион лет. Но концепт зашёл и я переписал на C+netsnmp.
Уверен что на питоне работало бы так же быстро, как и на С.

goodwin ★★
( 21.11.22 11:17:16 MSK )
Ответ на: комментарий от th3m3 21.11.22 11:15:05 MSK

[cppmm@damned compare]$ python --version Python 3.10.8 

Но я бы искал причину такого поведения не в версии питона, а в исходниках тестов. 😉

shell-script ★★★★★
( 21.11.22 11:21:55 MSK )
Ответ на: комментарий от shell-script 21.11.22 11:21:55 MSK

В Python 3.11 — ускорили инициализацию, быстрее должен быть запуск.

th3m3 ★★★★★
( 21.11.22 11:38:40 MSK )
Ответ на: комментарий от th3m3 21.11.22 11:38:40 MSK

Если и проявляется, то на чём-то более тяжёлом.

[cppmm@damned compare]$ python --version Python 3.10.8 [cppmm@damned compare]$ time ./python-world.py Hello, World! real 0m0,047s user 0m0,046s sys 0m0,000s [cppmm@damned compare]$ sudo eselect python set 2 [cppmm@damned compare]$ python --version Python 3.11.0 [cppmm@damned compare]$ time ./python-world.py Hello, World! real 0m0,044s user 0m0,033s sys 0m0,010s [cppmm@damned compare]$ 

shell-script ★★★★★
( 21.11.22 11:48:17 MSK )

Правильно топил. Но дело тут не в скорости, а в том что bash — это не ЯП, а шелл, его задача — комбинировать запуск\вывод\ввод внешних программ, что априори не может быть быстрее.

#!/bin/bash let a=1 if [[ $a == 1 ]];then echo "hello world"; fi 

Сколько внешних программ вызывает баш при обработке этого кода ?)

windows10 ★★★★
( 21.11.22 12:18:04 MSK )
Ответ на: комментарий от windows10 21.11.22 12:18:04 MSK

Скобочки надо было в if одинарные использовать, тогда в вопросе был бы подвох.

emorozov
( 21.11.22 12:23:33 MSK )
Ответ на: комментарий от untitl3d 21.11.22 10:20:34 MSK

Баш написан на си => баш быстрее.

Удивительно, но Python тоже написан на C. Поэтому, скорости равны!

emorozov
( 21.11.22 12:24:58 MSK )

bash ЕМНИП даже в байт-код не умеет компилироваться, не то что там jit. Так что на каком-нибудь перебирании массивов слив будет на порядок https://unix.stackexchange.com/questions/303157/is-there-something-wrong-with-my-script-or-is-bash-much-slower-than-python

Но спор абсолютно бессмысленный, разве что набросить на лоре, для задач, где применяют пистон баш не применяют, и наоборот.

goingUp ★★★★★
( 21.11.22 12:25:56 MSK )
Последнее исправление: goingUp 21.11.22 12:27:28 MSK (всего исправлений: 1)

Ответ на: комментарий от AntonI 21.11.22 10:08:03 MSK

«Мысль человеческая» довольно тормозная т.к. распространение сигнала по нервам медленнее чем в проводниках. Даже в ПДД прописана задержка на типичное время реакции для действия в котором головной моск почти не участвует. За одну секунду медленный старый комплюктер сделает дофига вычислений. А человеку если активно подумать надо при высокой неопределенности (ситуация совсем новая, т.е. требует логических выводов или обучения) — тут вообще идеал «овернайт», т.е. «переспать с проблемой». Итого, пользователь самая медленная часть системы.

slackwarrior ★★★★★
( 21.11.22 12:30:26 MSK )
Ответ на: комментарий от shell-script 21.11.22 10:43:55 MSK

Убери sleep(1) из c-world

firkax ★★★★★
( 21.11.22 12:41:32 MSK )

Конечно баш быстрее. Пока питонисты подсчитают все отступы, баш уже всё сделает.

Psilocybe ★★★★
( 21.11.22 12:50:22 MSK )
Ответ на: комментарий от slackwarrior 21.11.22 12:30:26 MSK

Скорость распространения сигнала по нервам не имеет значения, поскольку вычисления недискретны.

Вряд ли она вообще применима к организмам.

windows10 ★★★★
( 21.11.22 12:52:03 MSK )
Ответ на: комментарий от windows10 21.11.22 12:52:03 MSK

Имеет, потому что организмы медленнее компьютеров, независимо от механизма вычислений. гугл «Время реакции». Алсо сознание человеков медленне их подкорковых процессов и спинного моска, а подкорковые процессы не умеют в смену стратегии поведения, кроме выбора из уже известных (заученных до автоматизма), которые стратегии никогда на ходу не разрабатываются (должен сформироваться навык или сконсолидироваться память), это тупо экспериментально проверенные эмпиричеакие факты.

slackwarrior ★★★★★
( 21.11.22 13:00:50 MSK )

rupert ★★★★★
( 21.11.22 13:01:14 MSK )
Ответ на: комментарий от shell-script 21.11.22 10:43:55 MSK

Так-то Perl всё-равно делает Python как стоячего.

$ time perl python-world.py Hello, World! ________________________________________________________ Executed in 5.46 millis fish external usr time 2.96 millis 0.00 micros 2.96 millis sys time 2.52 millis 563.00 micros 1.96 millis 
$ time python3 python-world.py Hello, World! ________________________________________________________ Executed in 69.81 millis fish external usr time 57.88 millis 345.00 micros 57.54 millis sys time 11.15 millis 246.00 micros 10.91 millis 

Ja-Ja-Hey-Ho ★★★★
( 21.11.22 13:12:19 MSK )
Ответ на: комментарий от slackwarrior 21.11.22 13:00:50 MSK

Время реакции не имеет ничего общего с механизмом вычисления.

Если ты в свой выключатель света встроишь RPI, которая будет отлавливать нажатие выключателя через GPIO, а потом по сети по HTTP-протоколу будет посылать GET-запрос на сервер, который его обработает баш-скриптом if\then и пошлет в свою очередь запрос на RPI люстры, которая через реле зажжет лампочку — время реакции тоже будет медленное, но это не значит что а) Сервер тормознутый; б) Прямая цепочка «выключатель-лампочка» будет вычислять быстрее сервера.

Как и все остальное что ты написал — не имеют ничего общего со «скоростью».

Хочешь измерить скорость ? Запросто. Пиши на своем opencv алгоритм определения отличия леопарда от леопардового дивана и замеряй скорость определения им, а потом ребенком лет этак 10-ти. УДИВИШЬСЯ. Так и быть, в качестве форы разрешаю использовать камеру 120fps.

windows10 ★★★★
( 21.11.22 13:13:57 MSK )
Ответ на: комментарий от slackwarrior 21.11.22 13:00:50 MSK

Ты наверно компьютерщик какой-то, не понимаешь русского языка.

«Быстрее всего мысль человеческая» означает совсем не то, что ты понимаешь по компьютерски. Это означает что вот ты думаешь о том что перед тобой и вот подумал о Москве а затем сразу о заморском берегу. И это и означает что мысль быстрее чем ты добежишь туда пешком или долетишь на своей новомодной воздушной повозке. Сказки народные читать надо, а не только свои «маны».

Почему мы перешли с Python на Go

Поставщик высоконагруженного API Stream перешёл с Python на Go, хотя этот язык знают немногие. Причинами решения делимся под катом к старту курса по Backend-разработке на Go.

1. Производительность

Go — быстрый. Очень и очень быстрый. Его производительность близка к Java [сегодня используется на финансовом рынке для высокочастотного трейдинга — торговли на большой скорости — прим. ред.] или C++. В нашем случае Go чаще всего оказывался в 40 раз быстрее Python. Вот небольшое сравнение производительности этих языков.

2. Производительность языка имеет значение

Для многих приложений язык программирования — это просто связующее звено между программой и базой данных. И, как правило, производительность самого языка особо не важна. Но Stream — это поставщик API, который обеспечивает работу платформы с каналами и чатами более 700 компаний и более 500 миллионов конечных пользователей. Годами мы пытались оптимизировать Cassandra, PostgreSQL, Redis и т. д., но однажды наступает момент, когда пределы возможностей языка достигнуты.

Python — отличный язык, но для таких задач, как сериализация/десериализация, ранжирование и агрегирование, он довольно медлительный. Мы регулярно сталкивались с проблемами производительности, когда Cassandra получала данные за 1 мс, а следующие 10 мс Python тратил на превращение их в объекты.

3. Продуктивность разработчика и мало возможностей для креатива

Взгляните на этот небольшой кусок кода Go из статьи How I Start Go. Это отличная обучающая статьи и хорошая отправная точка для изучения Go.

Если вы новичок в Go, то в этом небольшом фрагменте кода вас мало что удивит. В нём показаны несколько присвоений, структуры данных, указатели, форматирование и встроенная HTTP-библиотека. Когда я только начал заниматься программированием, мне нравилось использовать тонкости возможностей Python. Python позволяет импровизировать с кодом, который вы пишете. Например, вы можете:

  • использовать метаклассы для самостоятельной регистрации классов при инициализации кода;
  • менять местами True и False;
  • добавлять функции в список встроенных функций;
  • перегружать операторы через magic-методы;
  • использовать функции в качестве свойств через декоратор @property.

С такими штуками интересно экспериментировать, и с этим согласится большинство программистов. Но написанный другими людьми код порой сложно понять. Go вынуждает вас придерживаться основ. Поэтому читать чужой код очень просто, и вы сразу понимаете, что в нём написано.

Конечно же, это «просто» зависит от вашего конкретного случая. Если вы хотите создать базовое CRUD API, то я бы порекомендовал всё-таки Django + DRF или Rails.

4. Конкурентность и каналы

Go, как и любой язык, стремится к простоте. Для него не придумывали множество новых понятий. Целью было создать простой язык — быстрый и удобный в работе. Единственная область, где в Go появилось нечто новое, — это горутины и каналы. (Если быть на 100% точными, то понятие CSP появилось в 1977 году, так что данное новшество — скорее уж, новый подход к старой идее).

Горутины — это упрощённый подход Go к потокам, а каналы — предпочтительный способ организации связи между горутинами. Горутины очень дёшево создавать, и они занимают лишь пару КБ дополнительной памяти. Поскольку горутины так мало весят, их можно запускать сотнями или даже тысячами одновременно. Коммуникацию между горутинами реализуют через каналы.

Среда выполнения в Go справляется со всеми сложностями. Реализация конкуренции через горутины и каналы позволяет с лёгкостью использовать доступные ядра ЦП и обрабатывать конкурентный ввод-вывод — и всё это делается без усложнения разработки. Для запуска функции в горутине требуется минимальный шаблонный код (если сравнивать с Python/Java). Вы просто добавляете к вызову функции ключевое слово go :

С подходом Go к конкурентности очень легко работать. Это интересный способ реализации, если проводить параллель с тем же Node, в котором разработчику нужно быть предельно внимательным к тому, как обрабатывается асинхронный код. Ещё один прекрасный аспект конкурентности в Go — детектор гонки. Вы всегда заметите любые состояния гонки в асинхронном коде.

Перевод твита

Несколько полезных ресурсов для знакомства с Go и каналами вы найдёте ниже.

5. Быстрая компиляция

Сейчас наш крупнейший микросервис, написанный на Go, компилируется за 4 секунды. Быстрая компиляция Go — это его главный плюс по сравнению с такими языками, как Java и C++, которые славятся своей медленной скоростью компиляции. Мне нравится сражаться на мечах, но ещё приятнее решать задачи, пока я помню, что должен делать мой код:

Перевод

— Эй, давайте работать!

6. Возможность создать команду

Начнём с очевидного: разработчиков Go гораздо меньше, чем для более старых языков (C++ и Java). По данным StackOverflow, 38% разработчиков знают Java, 19,3% разбираются в C++ и лишь 4,6% освоили Go. В данных на GitHub прослеживается схожая тенденция: Go используется чаще таких языков, как Erlang, Scala и Elixir, но его популярность ниже, чем у Java и C++.

К счастью, Go — очень простой и лёгкий в изучении язык. В нём есть нужные вам базовые функции и ничего более. Из новшеств можно выделить оператор defer и встроенное управление конкурентностью через горутины и каналы. Для приверженцев чистоты языка: Go далеко не первый реализовал эти концепции, но именно он сделал их популярными. Благодаря простоте Go любой разработчик на Python, Elixir, C++, Scala или Java, которого вы возьмёте в свою команду, разберётся в нём буквально за месяц.

Мы заметили, что, по сравнению с другими языками программирования, гораздо проще собрать команду разработчиков на Go. И если вы нанимаете сотрудников в таких конкурентных экосистемах, как Boulder and Amsterdam, то это весомое преимущество.

7. Прочная экосистема

Для таких команд, как наша (~20 человек), экосистема важна. Вы не сможете создать ценность для своих клиентов, если придётся заново изобретать всю функциональность с нуля. В Go есть отличная поддержка используемых нами инструментов. Надёжные библиотеки уже доступны для Redis, RabbitMQ, PostgreSQL, парсинга шаблонов, задач, выражений и RocksDB.

Экосистема Go в разы лучше, чем у таких новых языков, как Rust или Elixir. Разумеется, она не так хороша, как в Java, Python или Node, но это стабильная экосистема, а для многих базовых задач уже доступны качественные пакеты.

8. Gofmt, принудительное форматирование кода

Для начала, а что такое Gofmt? И нет, это не ругательство. Gofmt — это потрясающая утилита для командной строки; она встроена в компилятор Go специально для форматирования кода. В плане функциональности она очень похожа на autopep8 для Python.

Большинство из нас вообще-то не любит спорить о табах и пробелах, что бы ни показывали в сериале «Силиконовая долина». Форматирование должно быть единообразным, а сами его стандарты не особо важны. Gofmt избавляет от всех этих дискуссий, предлагая один официальный способ по форматированию кода.

9. gRPC и буферы протокола

Go предлагает первоклассную поддержку буферов протокола и gRPC. Оба эти инструмента прекрасно работают вместе для создания микросервисов, которые должны взаимодействовать через RPC. От вас всего лишь требуется написать манифест, в котором вы определяете, какие RPC-вызовы нужно делать и какие аргументы они принимают.

Затем из этого манифеста автоматически генерируются серверный и клиентский коды. Итоговый код получается быстрым, оставляет совсем небольшой сетевой отпечаток и крайне прост в работе. Из того же манифеста вы можете сгенерировать клиентский код для многих других языков, включая C++, Java, Python и Ruby. Так что оставьте в прошлом неоднозначные конечные точки REST для внутреннего трафика, когда вам каждый раз приходится прописывать почти один и тот же клиентский и серверный код.

1. Нехватка фреймворков

В Go нет какого-то одного главного фреймворка, как, например, Rails для Ruby, Django для Python или Laravel для PHP. Это предмет самых горячих споров в сообществе Go, поскольку многие считают, что вам вообще не нужны никакие фреймворки. В некоторых случаях я полностью с ними согласен. Но если кто-то захочет создать простой CRUD API, то гораздо удобнее сделать это на Django/DJRF, Rails Laravel или Phoenix.

Дополнение: в комментариях пишут, что есть несколько проектов, которые предоставляют фреймворк для Go. Основными фаворитами называют Revel, Iris, Echo, Macaron и Buffalo. Мы предпочли не использовать фреймворки в Stream. Но для многих новых проектов, которые нацелены на предоставление простого CRUD API, отсутствие основного фреймворка является серьёзным недочётом.

2. Обработка ошибок

Обработка ошибок в Go сводится к тому, что он просто возвращает ошибку из функции и ожидает, что ваш клиентский код сам её обработает (или вернёт ошибку на стек вызывающей программы). Такой подход вполне работоспособен, но можно запросто упустить из виду, когда что-то пошло не так, из-за чего не получится выдать пользователям информативную ошибку. Эту проблему решает пакет errors, позволяющий вам добавлять в ошибки контекст и трассировку стека.

Ещё одна проблема — можно случайно забыть обработать ошибку. Тут пригодятся инструменты статического анализа (errcheck и megacheck). Несмотря на работоспособность этих обходных решений, всё это кажется не совсем правильным. Вы ждёте, что язык будет поддерживать надлежащую обработку ошибок.

3. Управление пакетами

С момента написания этой статьи Go прошёл долгий путь в управлении пакетами. Эффективными решениями являются модули Go; их единственная проблема заключается в том, что они нарушают работу таких инструментов для статического анализа, как errcheck. Вот обучающая статья по Go и использованию модулей Go.

Управление пакетами в Go нельзя назвать идеальным. Там по умолчанию отсутствует возможность задавать конкретную версию зависимости и создавать воспроизводимые сборки. Системы управления пакетами в Python, Node и Ruby гораздо лучше. Но с правильными инструментами управление пакетами в Go работает вполне прилично.

Для управления зависимостями вы можете использовать Dep — он позволяет указывать и закреплять версии. Помимо этого, мы используем инструмент с открытым кодом под названием VirtualGo, который упрощает работу с несколькими проектами, написанными на Go.

Python или Go

Обновление: с момента написания этой статьи разница в производительности Python и Go возросла. (Go стал быстрее, а Python остался тем же). Мы провели интересный эксперимент: взяли наш функционал ранжирования каналов на Python и переписали его в Go. Взгляните на этот пример метода ранжирования:

Для его поддержки код на Python и на Go должен делать следующее:

  1. Разбирать выражение для оценки. В данном случае мы хотим превратить эту строку «simple_gauss(time)*popularity» в функцию, которая берёт активность в качестве входного значения и возвращает оценку на выходе.
  2. Создавать частично определённые функции на основе конфигурации JSON. Например, мы хотим, чтобы «simple_gauss» вызывала «decay_gauss» со шкалой в 5 дней, смещением в 1 день и коэффициентом убывания в 0,3.
  3. Разобрать конфигурацию «defaults» , чтобы у вас был резервный вариант на случай, если какое-то поле в активности не будет определено.
  4. Воспользоваться функцией из шага № 1, чтобы присвоить баллы всем активностям в канале.

Разработка Python-версии кода ранжирования заняла примерно 3 дня. Сюда вошли написание кода, модульные тесты и документация. Затем около 2 недель ушло на оптимизацию кода. Одна из оптимизаций переводила выражение оценки (simple_gauss(time)*popularity) в абстрактное синтаксическое дерево.

Кроме того, мы реализовали логику кеширования, которая предварительно вычисляла оценку для определённого времени в будущем. А разработка Go-версии кода, наоборот, заняла не более 4 дней. Дальнейшей оптимизации для работы не потребовалось. Первая часть разработки шла быстрее на Python, но в итоге версия для Go оказалась менее трудоёмкой.

Дополнительным плюсом было и то, что код Go работал примерно в 40 раз быстрее, чем наш самый хорошо оптимизированный код на Python. Это лишь один из примеров роста производительности, с которой мы столкнулись, перейдя на Go. Но, конечно же, такое сравнение — из серии «сопоставлять несопоставимое»:

  • код ранжирования был моим первым проектом на Go;
  • код Go писался после кода на Python, так что к тому времени я лучше понимал сценарий использования;
  • библиотека Go для разбора выражений была исключительно высокого качества.

Ваши доводы будут отличаться. На создание некоторых других компонентов нашей системы в Go уходило гораздо больше времени, чем в Python. В итоге мы заметили общую тенденцию: разрабатывать код на Go чуточку сложнее, но времени на его оптимизацию тратится в разы меньше.

Elixir или Go — заслуженное серебро

Ещё один опробованный нами язык — это Elixir. Он построен поверх виртуальной машины Erlang. Это удивительный язык; мы решили к нему присмотреться, поскольку у одного члена нашей команды имелся солидный опыт работы с Erlang. В своих примерах мы заметили, что исходная производительность Go выше.

Go и Elixir отлично справляются с тысячами параллельных запросов. Однако если присмотреться к производительности отдельного запроса, то для нас Go оказался в разы быстрее.

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

Кроме того, труднее найти/обучить разработчиков на Elixir. Все эти причины склонили чашу весов в сторону Go. Тем не менее у Elixir есть просто потрясающий фреймворк Phoenix, который однозначно заслуживает внимания.

Заключение

Go — это высокопроизводительный язык с отличной поддержкой конкурентности. Он почти такой же быстрый, как C++ и Java. На разработку кода в Go уходит чуть больше времени, чем в Python или Ruby, но вы существенно экономите на оптимизации кода. У нас есть небольшая команда разработчиков в Stream, который поддерживает работу каналов и чатов для более 500 миллионов конечных пользователей.

Благодаря сочетанию отличной экосистемы, быстрого обучения новых разработчиков, высокой производительности, стабильной поддержке конкурентности и эффективной среде разработки Go стал для нас отличным выбором.

Stream всё ещё пользуется Python для дашбордов, сайта и машинного обучения для персонализированных каналов. В ближайшее время мы не планируем попрощаться с Python, но в дальнейшем весь производительный код будет написан на Go.

Наш новый Chat API также полностью написан на Go. Если вы хотите узнать о языке больше, почитайте статьи из списка ниже. А если интересно познакомиться со Stream, начните с этого интерактивного урока.

Изучение Go

  • https://learnxinyminutes.com/docs/go/
  • https://tour.golang.org/
  • http://howistart.org/posts/go/1/
  • https://getstream.io/blog/building-a-performant-api-using-go-and-cassandra/
  • https://www.amazon.com/gp/product/0134190440
  • Go Rocket Tutorial

Горутины

  • https://gobyexample.com/channels
  • https://tour.golang.org/concurrency/2
  • http://guzalexander.com/2013/12/06/golang-channels-tutorial.html
  • https://www.golang-book.com/books/intro/10
  • https://www.goinggo.net/2014/02/the-nature-of-channels-in-go.html
  • Goroutines vs Green threads

Причины перехода на Go

  • https://movio.co/en/blog/migrate-Scala-to-Go/
  • https://hackernoon.com/why-i-love-golang-90085898b4f7
  • https://sendgrid.com/blog/convince-company-go-golang/
  • https://dave.cheney.net/2017/03/20/why-go

А мы поможем прокачать ваши навыки или с самого начала освоить профессию, востребованную в любое время:

  • Профессия Backend-разработчик на Go
  • Профессия Data Scientist

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *