Python против Bash - в каких задачах каждый из них опережает другие по производительности?

97

Очевидно, Python более удобен для пользователя, быстрый поиск в Google показывает много результатов, которые говорят, что, поскольку Python компилируется побайтно, он обычно быстрее. Я даже нашел это , что претензии , которые вы можете увидеть улучшение более чем 2000% по словарю на основе операций.

Какой у вас опыт по этому поводу? В какой задаче каждый явный победитель?

Доппельгангер
источник
6
На самом деле это не опрос, здесь нет предопределенных параметров, мне нужно некоторое представление о том, какой инструмент работает лучше всего.
Doppelganger

Ответы:

94

Типичный поток мэйнфреймов ...

Input Disk/Tape/User (runtime) --> Job Control Language (JCL) --> Output Disk/Tape/Screen/Printer
                                   |                          ^
                                   v                          |
                                   `--> COBOL Program --------' 

Типичный поток Linux ...

Input Disk/SSD/User (runtime) --> sh/bash/ksh/zsh/... ----------> Output Disk/SSD/Screen/Printer
                                   |                          ^
                                   v                          |
                                   `--> Python script --------'
                                   |                          ^
                                   v                          |
                                   `--> awk script -----------'
                                   |                          ^
                                   v                          |
                                   `--> sed script -----------'
                                   |                          ^
                                   v                          |
                                   `--> C/C++ program --------'
                                   |                          ^
                                   v                          |
                                   `--- Java program ---------'
                                   |                          ^
                                   v                          |
                                   :                          :

Оболочки - клей Linux

Оболочки Linux, такие как sh / ksh / bash / ... предоставляют средства обозначения ввода / вывода / управления потоком, очень похожие на старый язык управления заданиями для мэйнфреймов ... но на стероидах! Они сами по себе являются полными по Тьюрингу языками , оптимизированными для эффективной передачи данных и управления другим исполняемым процессам, написанным на любом языке, поддерживаемом ОС.

Большинство приложений Linux, независимо от того, на каком языке написана основная часть программы, зависят от сценариев оболочки, и Bash стал наиболее распространенным. Щелчок по значку на рабочем столе обычно запускает короткий сценарий Bash . Этот сценарий, прямо или косвенно, знает, где находятся все необходимые файлы, и устанавливает переменные и параметры командной строки, наконец, вызывая программу. Это простейшее использование оболочки.

Однако Linux в том виде, в каком мы его знаем, вряд ли был бы Linux без тысяч сценариев оболочки, которые запускают систему, реагируют на события, контролируют приоритеты выполнения и компилируют, настраивают и запускают программы. Многие из них довольно большие и сложные.

Оболочки предоставляют инфраструктуру, которая позволяет нам использовать готовые компоненты, которые связаны между собой во время выполнения, а не во время компиляции. Эти компоненты представляют собой самостоятельные программы, которые можно использовать по отдельности или в других комбинациях без перекомпиляции. Синтаксис для их вызова неотличим от синтаксиса встроенной команды Bash , и на самом деле существует множество встроенных команд, для которых также есть автономный исполняемый файл в системе, часто имеющий дополнительные параметры.

Между Python и Bash нет разницы в производительности на уровне всего языка. Это полностью зависит от того, как каждый из них закодирован и какие внешние инструменты вызываются.

Любой из хорошо известных инструментов, таких как awk, sed, grep, bc, dc, tr и т. Д., Оставит выполнение этих операций на любом языке в пыли. Тогда Bash предпочтительнее для всего, что не имеет графического пользовательского интерфейса, поскольку проще и эффективнее вызывать и передавать данные обратно из инструмента, подобного инструментам с Bash, чем из Python .

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

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

Пользовательский интерфейс

Одна из областей, в которой Python является явным победителем, - это пользовательский интерфейс. Это делает его отличным языком для создания локальных или клиент-серверных приложений, поскольку он изначально поддерживает графику GTK и гораздо более интуитивно понятен, чем Bash .

Баш понимает только текст. Другие инструменты должны быть вызваны для графического интерфейса пользователя и данных, переданных от них. Python скрипт является одним из вариантов. Более быстрые, но менее гибкие варианты - это двоичные файлы, такие как YAD, Zenity и GTKDialog .

В то время как оболочки, такие как Bash, хорошо работают с графическими интерфейсами, такими как Yad , GtkDialog (встроенный XML-подобный интерфейс для функций GTK +) , диалогом и xmessage , Python гораздо более эффективен и поэтому лучше подходит для сложных окон графического интерфейса.

Резюме

Сборка с использованием сценариев оболочки похожа на сборку компьютера с готовыми компонентами, как настольные ПК.

Сборка с использованием Python , C ++ или любого другого языка больше похожа на сборку компьютера путем спайки микросхем (библиотек) и других электронных компонентов вместе, как это делают смартфоны.

Наилучшие результаты обычно достигаются при использовании комбинации языков, каждый из которых может делать то, что умеет лучше всего. Один разработчик называет это « программированием полиглота ».

DocSalvager
источник
16
Я не понимаю, как можно принять ответ. Он не дает никаких сведений о том, для каких задач эти двое больше подходят.
vigilancer
2
@vigilancer Я надеюсь, что опубликованные изменения и дополнения будут вам полезны.
DocSalvager 08
1
Хотя я согласен с другими комментариями, это не совсем ответ на вопрос. Это один из лучших ответов, которые я когда-либо читал!
Джим Митченер,
71

Как правило, bash работает лучше, чем python, только в тех средах, где python недоступен. :)

Серьезно, мне приходится иметь дело с обоими языками ежедневно, и я сразу же возьму python вместо bash, если у меня будет выбор. Увы, я вынужден использовать bash на некоторых «маленьких» платформах, потому что кто-то (ошибочно, ИМХО) решил, что python «слишком велик», чтобы уместиться.

Хотя верно, что bash может быть быстрее, чем python для некоторых избранных задач, он никогда не может быть таким быстрым в разработке или таким простым в обслуживании (по крайней мере, после того, как вы проработаете 10 строк кода или около того). Единственная сильная сторона Bash по отношению к python, ruby, lua и т. Д. - его повсеместность.

Кевин Литтл
источник
4
Разве Python уже не в каждом Linux / Unix, даже в MacOS? Мне любопытно, какие операции в bash выполняются быстрее - насколько я понял, его вызов разных отдельных команд делает его намного медленнее, чем команды Python osили shutilмодуля.
NoBugs
1
@NoBugs Это определенно не будет в каждом дистрибутиве Linux / Unix. Он почти наверняка присутствует во всех основных дистрибутивах Linux (например, в дистрибутивах на основе Debian, Slackware и т. Д.) И в Mac OS X, однако, если вы создадите свой собственный ISO-образ с помощью yocto ( yoctoproject.org ), то у вас не может быть его, поскольку вы настраиваете каждый пакет самостоятельно. Но, вероятно, можно с уверенностью сказать, что для любой крупной современной ОС Unix она будет поставляться с установленным python2 (по крайней мере) и, возможно, также с python3.
dylnmc
Python - отличный язык сценариев для сложных задач, таких как полнофункциональный графический интерфейс. Не менее важно, что он обеспечивает соблюдение передовых методов программирования, поэтому программы легче поддерживать. Bash требует применения передовых практик, изученных в других местах, чтобы его можно было поддерживать. При этом и использование диалоговой утилиты графического интерфейса пользователя или Python для пользовательского интерфейса обеспечивает превосходную производительность (благодаря чрезвычайно быстрым служебным программам, вызываемым из Bash), а также хороший UX.
DocSalvager
34

Эффективность разработчика имеет для меня гораздо большее значение в сценариях, где и bash, и Python являются разумным выбором.

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

Большим преимуществом Python является обработка угловых файлов, в то время как у него есть glob , shutil , subprocess и другие для общих нужд сценариев.

Роджер Пэйт
источник
5
Вопрос был направлен на сравнение «по производительности», которое подразумевает производительность компьютера, а не производительность разработчика. Смотрите мои тесты производительности в другом ответе.
Grzegorz Luczywo
25

При написании скриптов производительность не имеет значения (в большинстве случаев).
Если вас волнует производительность, вопрос «Python vs Bash» - ложный.

Python :
+ проще писать
+ проще в обслуживании
+ проще повторное использование кода (попробуйте найти универсальный безошибочный способ включения файлов с общим кодом sh, смею вас)
+ с ним тоже можно выполнять ООП!
+ более простой разбор аргументов. ну не проще, точно. на мой вкус, это будет слишком многословно, но в python argparseвстроены средства.
- уродливый уродливый «подпроцесс». постарайтесь связать команды и не кричать реку, насколько уродливым станет ваш код. особенно если вам важны коды выхода.

Баш :
+ вездесущность, как было сказано ранее, действительно.
+ простое объединение команд. вот как вы просто склеиваете разные команды. Также Bash(нет sh) есть некоторые улучшения, например pipefail, поэтому цепочки действительно короткие и выразительные.
+ не требует установки сторонних программ. могут быть выполнены сразу.
- Боже, здесь полно ловушек. IFS, CDPATH .. тысячи из них.

Если вы пишете скрипт больше 100 LOC: выберите Python.
Если вам нужно манипулирование путями в скрипте: выберите Python. (3)
Если что-то вроде, aliasно немного сложнее: выберите Bash / sh

В любом случае, нужно попробовать обе стороны, чтобы понять, на что они способны.

Возможно, ответ можно дополнить упаковкой и точками поддержки IDE, но я не знаком с этими сторонами.

Как всегда, вы должны выбрать бутерброд с какашкой или гигантский душ. И помните, всего несколько лет назад Perl был новой надеждой. Где это сейчас.

бдительный
источник
4
Да, код с bash живет вечно. Я много писал на Perl, теперь они бесполезны.
Raymond gsh
Просто для перспективы ... Текущий самый крупный сценарий, который я написал, который я использую весь день каждый день, весит 4121 строку фактического, без комментариев или пустого кода bash. С подробными комментариями и прочим, получается 7261 строка. Он сопровождается файлом справки, состоящим из документации, подобной man-странице, для каждой функции, которая составляет еще 6650 строк. У каждой функции есть опция, которая может мгновенно извлекать и отображать свой текст справки в наилучшей доступной форме вывода, которая в настоящее время включает 3 версии YAD, Zenity, диалог или просто текст CLI. Я называю это «комплектом». это версия 44 на момент написания этой статьи.
DocSalvager
Это тяжело! (c)
vigilancer
1
Я не думаю, что LoC действительно является решающим фактором при выборе Python. Более того, насколько сложна задача, которую вы выполняете? Если вы просто связываете 100 команд, это, вероятно, нормально, если в bash всего 30 LoC, но это может быть легче понять в Python - используйте python.
JFord 08
@ Акито, когда ничего не трогает, все в порядке. но есть несколько ситуаций, когда что-то может пойти не так. вы установили нестандартное значение и забыли его очистить. что-то извне изменило его, но ваш сценарий полагается на значение по умолчанию и так далее. всегда нужно помнить об IFS, потому что некоторые инструменты неявно его используют.
дозор
22

По производительности bash превосходит python по времени запуска процесса.

Вот некоторые измерения моего ноутбука с Core i7 под управлением Linux Mint:

Starting process                       Startup time

empty /bin/sh script                   1.7 ms
empty /bin/bash script                 2.8 ms
empty python script                    11.1 ms
python script with a few libs*         110 ms

* Загружаемые библиотеки Python: os, os.path, json, time, requests, threading, subprocess

Это показывает огромную разницу, однако время выполнения bash быстро ухудшается, если ему нужно делать что-то разумное, поскольку обычно он должен вызывать внешние процессы.

Если вам важна производительность, используйте bash только для:

  • действительно простые и часто вызываемые скрипты
  • скрипты, которые в основном вызывают другие процессы
  • когда вам нужно минимальное трение между ручными административными действиями и сценариями - быстро проверьте несколько команд и поместите их в file.sh
Гжегож Лучиво
источник
... и /bin/echoпревосходит bash настолько, что это сложно измерить. Итак, вместо запуска bash вы можете использовать /bin/echo mycommand > named_pipe(выводить команды / сообщения в именованный канал или сокет) ... и иметь фоновый процесс Python, читающий команды / инструкции из этого канала и запускающий их. Так что bash - не совсем хорошая «оптимизация затрат на запуск».
Cezary Baginski
Обычно предполагается использовать потоки вместо процессов, когда задача действительно короткая и быстрая. Несколько процессов - это вещь высокого уровня, и если запуск одного происходит в течение полсекунды, это по большей части кажется вполне разумным, не так ли?
Тимоти Свон
16

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

Что быстрее? Ни то, ни другое, потому что здесь вы не сравниваете яблоки с яблоками. Если вам нужно было отсортировать текстовый файл ascii и вы использовали такие инструменты, как zcat, sort, uniq и sed, тогда вы будете курить с точки зрения производительности Python.

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

Джастин
источник
13
Итак, вся мораль моей напыщенной речи такова: используйте правильный инструмент для правильной работы.
Джастин
2
плавающая точка поддерживается такими инструментами, как awk, bc, и оболочками, такими как zsh / ksh, так почему вы говорите, что Python побеждает?
ghostdog74
4
Потому что это не Bash. Я указывал на явную разницу. Эти инструменты используются в сценарии оболочки, но сам собственный Bash не поддерживает операции с плавающей запятой.
Джастин
2
Нет. Попробуйте сами. gzip большой файл журнала и используйте zcat, sort и т.д., чтобы выполнить некоторую фильтрацию, а затем использовать собственные библиотеки Python. Это значительно быстрее при использовании собственных инструментов.
Джастин
6
@justin, да, это не Bash, но они существуют с древних времен и часто используются в сценариях оболочки. если вам нужна плавающая точка, используйте awk / bc. Комбинация этих инструментов делает сценарии оболочки такими же мощными, как и Python.
ghostdog74
12

Если вы хотите собрать быструю утилиту с минимальными усилиями, подойдет bash. Для оболочки приложения bash бесценен.

Все, что может заставлять вас возвращаться снова и снова, чтобы добавлять улучшения, вероятно (хотя и не всегда) лучше подходит для такого языка, как Python, поскольку код Bash, состоящий из более чем 1000 строк, становится очень болезненно поддерживать. Код на Bash также раздражает при отладке, когда он становится длинным .......

Частично проблема с такими вопросами заключается в том, что, по моему опыту, сценарии оболочки обычно представляют собой настраиваемые задачи. Я встречал очень мало задач по написанию сценариев оболочки, решение которых уже есть в свободном доступе.

замхассам
источник
8

Я считаю, что есть 2 сценария, в которых производительность Bash по крайней мере равна:

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

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

посторонний
источник
4

Я отправляю этот поздний ответ в первую очередь потому, что Google нравится этот вопрос.

Я считаю, что проблема и контекст действительно должны касаться рабочего процесса, а не инструментов. Общая философия всегда такова: «Используйте правильный инструмент для работы». Но прежде чем это произойдет, многие часто забывают, теряясь в инструментах: «Сделайте свою работу».

Когда у меня возникает проблема, которая не решена полностью, я почти всегда начинаю с Bash. Я решил некоторые грубые проблемы в больших сценариях Bash, которые можно читать и поддерживать.

Но когда проблема начинает выходить за рамки того, что нужно сделать Bash? У меня есть несколько проверок, которые я использую для предупреждений:

  1. Хотел бы я, чтобы у Bash были массивы 2D (или выше)? Если да, то пора понять, что Bash - не лучший язык для обработки данных.
  2. Выполняю ли я больше работы по подготовке данных для других утилит, чем на самом деле запускаю эти утилиты? Если да, то пора еще раз осознать, что Bash - не лучший язык для обработки данных.
  3. Мой сценарий просто становится слишком большим для управления? Если да, важно понимать, что, хотя Bash может импортировать библиотеки сценариев, ему не хватает системы пакетов, как в других языках. По сравнению с большинством других, это действительно язык, который можно использовать как «свой собственный». Опять же, он имеет огромное количество встроенных функций (некоторые говорят слишком много ...)

Этот список можно продолжить. В итоге, когда вы усерднее работаете над тем, чтобы ваши скрипты работали, добавляя функции, пришло время покинуть Bash.

Предположим, вы решили перенести свою работу на Python. Если ваши сценарии Bash чистые, первоначальное преобразование довольно простое. Есть даже несколько конвертеров / переводчиков, которые сделают за вас первый проход.

Следующий вопрос: от чего вы отказываетесь от перехода на Python?

  1. Все вызовы внешних утилит должны быть обернуты чем-то из subprocessмодуля (или его эквивалента). Есть несколько способов сделать это, и до версии 3.7 требовалось некоторое усилие, чтобы сделать это правильно (версия 3.7 улучшена subprocess.run()для самостоятельной обработки всех распространенных случаев).

  2. Удивительно, но в Python нет стандартной независимой от платформы неблокирующей утилиты (с тайм-аутом) для опроса клавиатуры (stdin). Команда Bash read- отличный инструмент для простого взаимодействия с пользователем. Чаще всего я использую счетчик, пока пользователь не нажмет клавишу, а также выполняю функцию опроса (с каждым шагом счетчика), чтобы убедиться, что все по-прежнему работает нормально. Это более сложная проблема, чем может показаться на первый взгляд, поэтому я часто просто звоню в Bash: дорого, но он делает именно то, что мне нужно.

  3. Если вы разрабатываете встраиваемую систему или систему с ограничением памяти, объем памяти Python может быть во много раз больше, чем у Bash (в зависимости от поставленной задачи). Кроме того, почти всегда в памяти уже есть экземпляр Bash, что может не относиться к Python.

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

  5. Python имеет самую полную систему пакетов на планете. Когда Bash становится даже немного сложным, у Python, вероятно, есть пакет, который превращает целые фрагменты Bash в один вызов. Однако поиск подходящего пакета (ов) для использования - самая большая и самая сложная часть становления Pythonista. К счастью, Google и StackExchange - ваши друзья.

BobC
источник
2

Я не знаю, верно ли это, но я обнаружил, что python / ruby ​​работает намного лучше для скриптов, в которых есть много математических вычислений. В противном случае придется использовать dcкакой-нибудь другой «калькулятор произвольной точности». Это просто становится очень большой болью. С python у вас гораздо больше контроля над числами с плавающей запятой и целыми числами, и намного проще выполнять много вычислений, а иногда.

В частности, я бы никогда не стал работать со сценарием bash для обработки двоичной информации или байтов. Вместо этого я бы использовал что-то вроде python (возможно), C ++ или даже Node.JS.

dylnmc
источник
Арифметика Bash является строго целочисленной, поэтому вы должны выполнять операции с плавающей запятой, вызывая что-то еще (например, awk или dc) и собирая вывод из него. Простые денежные операции часто можно сделать внутренне, просто умножив на 100 и изменив десятичную точку в выводе.
DocSalvager
0

С точки зрения производительности оба могут делать одно и то же, поэтому возникает вопрос, что экономит больше времени на разработку?

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

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

Вдобавок Bash очень снисходительно относится к тому, как на нем писать. Это означает, что он будет хорошо работать для более широкого разнообразия контекстов, но также полагается на программиста, имеющего намерение кодировать чисто безопасным способом. В противном случае Bash не помешает вам навести беспорядок.

Python более структурирован по стилю, поэтому беспорядочный программист не будет таким запутанным. Он также будет работать в операционных системах за пределами Linux, что делает его более подходящим, если вам нужна такая переносимость.

Но вызвать другие команды не так просто. Так что, если ваша операционная система - Unix, скорее всего, вы обнаружите, что разработка на Bash - это самый быстрый способ разработки.

Когда использовать Bash:

  • Это неграфическая программа или движок графической.
  • Это только для Unix.

Когда использовать Python:

  • Это графическая программа.
  • Он должен работать в Windows.
Альберто Сальвия Новелла
источник