Python vs Bash - In which kind of tasks each one outruns the other performance-wise?

Obviously Python is more user friendly, a quick search on google shows many results that say that, as Python is byte-compiled is usually faster. I even found this that claims that you can see an improvement of over 2000% on dictionary-based operations.

What is your experience on this matter? In which kind of task each one is a clear winner?

139967 次浏览

我认为有两种情况下 Bash 的性能至少是相同的:

  • 命令行实用程序脚本
  • 只需要很短时间执行的脚本; 启动 Python 解释器所需的时间比操作本身还要多

也就是说,我通常不太关心脚本语言本身的表现。如果性能是一个真正的问题,那么您不需要编写脚本,而是编写程序(可能使用 Python)。

Developer efficiency matters much more to me in scenarios where both bash and Python are sensible choices.

Some tasks lend themselves well to bash, and others to Python. It also isn't unusual for me to start something as a bash script and change it to Python as it evolves over several weeks.

Python 的一大优势是在处理文件名的边缘情况下,它有 一团Shutil子流程和其他用于常见脚本需求的工具。

Bash 主要是一个批处理/shell 脚本语言,对各种数据类型的支持要少得多,控制结构也有各种各样的怪癖——更不用说兼容性问题了。

哪个更快?都不是,因为你在这里不是在比较苹果和苹果。如果必须对 ascii 文本文件进行排序,并且正在使用 zcat、 sort、 uniq 和 sed 等工具,那么您将在 Python 性能方面受益匪浅。

However, if you need a proper programming environment that supports floating point and various control flow, then Python wins hands down. If you wrote say a recursive algorithm in Bash and Python, the Python version will win in an order of magnitude or more.

通常,bash 仅在 python 不可用的环境中比 python 工作得更好。 :)

Seriously, I have to deal with both languages daily, and will take python instantly over bash if given the choice. Alas, I am forced to use bash on certain "small" platforms because someone has (mistakenly, IMHO) decided that python is "too large" to fit.

对于某些选择的任务,bash 确实可能比 python 快,但它的开发速度永远不会像 Python 那样快,也不会像 Python 那样易于维护(至少在超过10行代码之后)。巴斯唯一的强项是蟒蛇、红宝石或 Lua 等,它无处不在。

如果您希望以最少的努力拼凑出一个快速实用程序,bash 是个不错的选择。对于应用程序的包装器来说,bash 是非常宝贵的。

任何可能让您反复添加改进的内容可能(尽管并不总是)更适合 Python 这样的语言,因为包含1000多行代码的 Bash 代码维护起来非常麻烦。Bash 代码长了也会让调试变得烦人... ..。

Part of the problem with these kind of questions is, from my experience, that shell scripts are usually all custom tasks. There have been very few shell scripting tasks that I have come across where there is already a solution freely available.

典型的主机流程。

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                          |
:                          :

Shell 是 Linux 的粘合剂

像 sh/ksh/Bash/... 这样的 Linux shell 提供输入/输出/流控制指定工具,非常类似于旧的大型机作业控制语言... 但是非常类似!他们是 图灵完整语言在他们自己的权利,同时被优化,以有效地传递数据和控制,从其他执行过程写在任何语言的 O/S 支持。

大多数 Linux 应用程序,不管大部分程序是用什么语言编写的,都依赖于 shell 脚本,而 巴斯已经成为最常见的语言。单击桌面上的图标通常会运行一个简短的 巴斯脚本。该脚本直接或间接地知道所有需要的文件在哪里,并设置变量和命令行参数,最后调用程序。这是 shell 最简单的用法。

然而,如果没有成千上万的 shell 脚本来启动系统、响应事件、控制执行优先级以及编译、配置和运行程序,我们所知道的 Linux 很难称得上是 Linux。其中许多是相当大和复杂的。

Shell 提供了一种基础结构,使我们可以使用在运行时而不是在编译时链接在一起的预构建组件。这些组件本身就是独立的程序,可以单独使用,也可以在其他组合中使用,无需重新编译。调用它们的语法与 巴斯内建命令的语法没有什么区别,事实上,有许多内建命令在系统上也有一个独立的可执行文件,通常还有其他选项。

Python巴斯在性能上没有语言范围的差异。这完全取决于如何对每个工具进行编码以及调用哪些外部工具。

任何像 Awk,sed,grep,bc,dc,tr,这样的知名工具都会把用任何一种语言做这些操作抛到九霄云外。因此,对于任何没有图形用户界面的工具,巴斯都是首选,因为使用类似于使用 巴斯的工具来调用和传递数据比使用 巨蟒更容易、更有效。

Performance

这取决于 巴斯 shell 脚本调用哪个程序,以及它们是否适合给定的子任务,总体吞吐量和/或响应能力是优于等效的 巨蟒还是劣于等效的 巨蟒。与大多数语言一样,使问题复杂化的是 巨蟒也可以调用其他可执行程序,尽管它比较麻烦,因此不常使用。

用户界面

巨蟒显然是赢家的一个领域是用户界面。这使它成为构建本地或客户机-服务器应用程序的优秀语言,因为它本身支持 GTK 图形,并且比 巴斯更加直观。

Bash 只能理解文本。必须为 GUI 调用其他工具以及从它们传回的数据。巨蟒脚本是一种选择。更快但不太灵活的选项是像 YAD, Zenity, and GTKDialog这样的二进制文件。

While shells like 巴斯 work well with GUIs like 亚德, GtkDialog (GTK + 函数的嵌入式类 XML 接口), 对话, and Xmessage, 巨蟒 is much more capable and so better for complex GUI windows.

摘要

用 shell 脚本构建就像用现成的组件组装一台计算机,就像台式计算机那样。

使用 巨蟒C + + 或大多数其他语言构建计算机更像是将芯片(库)和其他电子部件焊接在一起,就像智能手机一样。

最好的结果通常是通过使用 语言的组合获得的,每个人都可以做他们最擅长的事情。一个开发者称之为“ 通晓多种语言的程序设计”。

在流程启动时,性能方面的 bash 优于 python。

下面是我的 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,request,threading,subprocess

This shows a huge difference however bash execution time degrades quickly if it has to do anything sensible since it usually must call external processes.

如果您关心性能,那么只在以下情况下使用 bash:

  • 非常简单,经常被称为脚本
  • 主要调用其他进程的脚本
  • when you need minimal friction between manual administrative actions and scripting - fast check a few commands and place them in the file.sh

我不知道这是否准确,但我发现 python/ruby 对于具有大量数学计算的脚本要好得多。否则,你必须使用 dc或其他一些“任意精度计算器”。只会变成一种巨大的痛苦。使用 python,您可以更好地控制 float 和 int,并且执行大量计算有时也更容易。

特别是,我绝不会使用 bash 脚本来处理二进制信息或字节。相反,我会使用 python (也许)或 C + + ,甚至 Node.JS。

When you writing scripts performance does not matter (in most cases).
如果您关心性能,那么“ Python vs Bash”是一个错误的问题。

Python :
写起来更容易
更容易维护
+ 更容易的代码重用(尝试找到通用的错误防范方法,包括在 sh中的公共代码文件,我敢说你)
+ 你也可以用它来做 OOP!
+ 更简单的参数解析。确切地说,不是更容易。它仍然会过于冗长,我的口味,但巨蟒有 argparse设施内置。
丑陋丑陋的“子进程”。尝试连锁命令,而不是哭诉你的代码会变得多么丑陋。特别是如果你在乎出口密码的话。

Bash :
无处不在,正如前面所说,的确如此。
+ 简单命令链接。这就是如何用简单的方法将不同的命令粘合在一起的方法。而且 Bash(而不是 sh)也有一些改进,比如 pipefail,所以链接真的很短而且有表现力。
+ do not require 3rd-party programs to be installed. can be executed right away.
天啊,到处都是陷阱 IFS CDPATH 成千上万的陷阱。

如果编写的脚本大于100 LOC: 选择 巨蟒
如果需要在脚本中进行路径操作,请选择 < em > Python (3)

If one need somewhat like alias but slightly complicated: choose Bash/sh

无论如何,我们应该尝试双方了解他们的能力。

也许答案可以扩展包装和 IDE 支持点,但我不熟悉这方面。

一如既往,你必须从大便三明治和巨型灌肠器中做出选择。 请记住,就在几年前,Perl 还是新的希望。

我发布这个最新的回答主要是因为谷歌喜欢这个问题。

我相信问题和背景真的应该是关于工作流,而不是工具。总的理念是“为工作使用正确的工具”但在此之前,许多人在迷失于工具之中时常常会忘记一句话: “把工作做好。”

当我遇到一个没有完全定义的问题时,我几乎总是从 Bash 开始。我已经用大型 Bash 脚本解决了一些棘手的问题,这些脚本既可读又可维护。

但是问题什么时候开始超出 Bash 应该被要求做的事情呢?我有一些支票用来警告我:

  1. 我希望 Bash 有2D (或更高)数组吗?如果答案是肯定的,那么是时候认识到 Bash 并不是一种优秀的数据处理语言了。
  2. 为其他实用程序准备数据的工作是否比实际运行这些实用程序所做的工作更多?如果答案是肯定的,那么我们再次认识到 Bash 并不是一种优秀的数据处理语言。
  3. 我的脚本是否变得太大而无法管理?如果是,那么必须认识到,虽然 Bash 可以导入脚本库,但它缺乏像其他语言一样的包系统。与大多数其他语言相比,它实际上是一种“滚动你自己”的语言。不过话说回来,它内置了大量的功能(有人说太多了... ...)

还有很多。底线是,当您正在更努力地工作以保持脚本运行并添加特性时,是时候离开 Bash 了。

让我们假设您已经决定将您的工作转移到 Python。如果您的 Bash 脚本是干净的,那么初始转换非常简单。甚至还有几个转换器/翻译器可以为您完成第一轮转换。

The next question is: What do you give up moving to Python?

  1. 对外部实用程序的所有调用都必须包装在来自 subprocess模块(或等效模块)的内容中。有多种方法可以做到这一点,直到3.7,它需要一些努力才能得到正确的(3.7改进的 subprocess.run()自己处理所有常见的情况)。

  2. 令人惊讶的是,Python 没有用于轮询键盘(stdin)的标准平台无关的非阻塞实用程序(带超时)。Bashread命令对于简单的用户交互来说是一个非常棒的工具。我最常用的方法是显示一个 spinner,直到用户按下一个键,同时运行一个轮询函数(每个 spinner 步骤)以确保一切运行正常。这是一个比一开始看起来更难的问题,所以我经常简单地调用 Bash: Expensive,但它正好满足我的需要。

  3. 如果您在嵌入式系统或内存受限的系统上开发,Python 的内存占用可能是 Bash 的许多倍(取决于手头的任务)。另外,内存中几乎总是有一个 Bash 实例,而 Python 可能不是这样。

  4. 对于运行一次并快速退出的脚本,Python 的启动时间可能比 Bash 长得多。但是如果脚本包含重要的计算,Python 很快就会领先。

  5. Python 拥有世界上最全面的软件包系统。当 Bash 变得稍微复杂一些时,Python 可能有一个包,使得 Bash 的整个块成为一个单独的调用。然而,找到正确的软件包来使用是成为 Python 操作系统工作者的最大和最令人畏惧的部分。幸运的是,Google 和 StackExchange 是你的朋友。

在性能方面,两者都可以做同样的事情,因此问题就变成了哪一种方法可以节省更多的开发时间?

Bash 依赖于调用其他命令,并通过管道将它们用于创建新的命令。这样做的好处是,您可以仅使用从其他人那里借来的代码快速创建新程序,而不管他们使用的是什么编程语言。

这还有一个副作用,就是可以很好地抵制子命令的更改,因为它们之间的接口只是纯文本。

此外,Bash 对于如何在其上编写内容非常宽容。这意味着它将在更广泛的上下文中工作得很好,但是它也依赖于程序员希望以一种干净安全的方式进行编码。否则巴斯不会阻止你制造混乱。

Python is more structured on style, so a messy programmer won't be as messy. It will also work on operating systems outside Linux, making it instantly more appropriate if you need that kind of portability.

但是调用其他命令就不那么简单了。因此,如果您的操作系统是 Unix,那么您将发现在 Bash 上开发是最快的开发方式。

何时使用 Bash:

  • 它是一个非图形化的程序,或者说是一个图形化程序的引擎。
  • 这是 Unix 专用的。

何时使用 Python:

  • 这是一个图形化的程序。
  • 它应该可以在视窗上工作。