gan*_*ssh 29 performance python process-management bc
我正在分别6^6^6使用python和评估表达式bc。
python文件的内容是print 6**6**6. 当我执行时time python test.py,我得到的输出为
real 0m0.067s
user 0m0.050s
sys 0m0.011s
Run Code Online (Sandbox Code Playgroud)
然后,我运行了time echo 6^6^6 | bc给我以下输出的命令
real 0m0.205s
user 0m0.197s
sys 0m0.005s
Run Code Online (Sandbox Code Playgroud)
从这些结果可以清楚地看出,python 和 bc 所用的 sys 时间分别为 11 毫秒和 5 毫秒。在bc命令跑赢蟒蛇在SYS时的水平,但是当它涉及到用户和实时蟒蛇比BC快近4倍。那里可能有什么。我没有对这些过程给予任何优先考虑。我试图了解这种情况。
And*_*lke 25
Python在启动时导入大量文件:
% python -c 'import sys; print len(sys.modules)'
39
Run Code Online (Sandbox Code Playgroud)
这些中的每一个都需要更多的尝试来打开 Python 文件,因为定义模块的方法有很多:
% python -vv -c 'pass'
# installing zipimport hook
import zipimport # builtin
# installed zipimport hook
# trying site.so
# trying sitemodule.so
# trying site.py
# trying site.pyc
# trying /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site.so
# trying /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/sitemodule.so
# trying /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site.py
# /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site.pyc matches /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site.py
import site # precompiled from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site.pyc
# trying os.so
# trying osmodule.so
# trying os.py
# trying os.pyc
# trying /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.so
# trying /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/osmodule.so
# trying /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py
# /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc matches /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py
import os # precompiled from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc
...
Run Code Online (Sandbox Code Playgroud)
每个“尝试”,除了那些内置的,都需要一个操作系统级/系统调用,每个“导入”似乎触发了大约 8 个“尝试”消息。(有一些方法可以使用 zipimport 减少这种情况,并且 PYTHONPATH 中的每个路径都可能需要再次调用。)
这意味着在 Python 在我的机器上启动之前有将近 200 个 stat 系统调用,并且“time”将其分配给“sys”而不是“user”,因为用户程序正在等待系统执行操作。
相比之下,正如 terdon 所说,“bc”的启动成本并不高。查看 dtruss 输出(我有一台 Mac;对于基于 Linux 的操作系统为“strace”),我看到 bc 没有自己进行任何 open() 或 stat() 系统调用,除了加载一些共享库是开始,当然 Python 也是如此。此外,在准备好处理任何内容之前,Python 需要读取更多文件。
等待磁盘很慢。
您可以通过执行以下操作来了解 Python 的启动成本:
time python -c pass
Run Code Online (Sandbox Code Playgroud)
在我的机器上是0.032s,而'print 6**6**6'是0.072s,所以启动成本是总时间的1/2,计算+转换为十进制是另一半。尽管:
time echo 1 | bc
Run Code Online (Sandbox Code Playgroud)
需要 0.005s,而 "6^6^6" 需要 0.184s,所以 bc 的幂运算比 Python 慢 4 倍以上,即使它的启动速度快 7 倍。
ter*_*don 11
我在 SO 上找到了一个很好的答案,解释了不同的领域:
Real 是挂钟时间 - 从通话开始到结束的时间。这是所有经过的时间,包括其他进程使用的时间片和进程阻塞的时间(例如,如果它正在等待 I/O 完成)。
User 是进程内用户模式代码(内核外)花费的 CPU 时间量。这只是用于执行进程的实际 CPU 时间。其他进程和进程花费的阻塞时间不计入这个数字。
Sys 是进程内在内核中花费的 CPU 时间量。这意味着在内核中执行系统调用所花费的 CPU 时间,而不是库代码,后者仍在用户空间中运行。与“用户”一样,这只是进程使用的 CPU 时间。有关内核模式(也称为“主管”模式)和系统调用机制的简要说明,请参见下文。
因此,在您的具体示例中,python 版本在实际完成时间方面更快。但是,python 方法在内核空间中花费更多时间,调用内核函数。该bc命令基本上不花时间在内核空间中,所有时间都花在用户空间中,大概是运行内部bc代码。
这对您没有任何影响,您真正关心的唯一信息是real启动命令和获得输出之间的实际时间。
您还应该意识到这些微小的差异并不稳定,它们还取决于系统的负载,并且每次运行命令时都会发生变化:
$ for i in {1..10}; do ( time python test.py > /dev/null ) 2>&1; done | grep user
user 0m0.056s
user 0m0.052s
user 0m0.052s
user 0m0.052s
user 0m0.060s
user 0m0.052s
user 0m0.052s
user 0m0.056s
user 0m0.048s
user 0m0.056s
$ for i in {1..10}; do ( time echo 6^6^6 | bc > /dev/null ) 2>&1; done | grep user
user 0m0.188s
user 0m0.188s
user 0m0.176s
user 0m0.176s
user 0m0.172s
user 0m0.176s
user 0m0.180s
user 0m0.172s
user 0m0.172s
user 0m0.172s
Run Code Online (Sandbox Code Playgroud)
Bra*_*iam 10
我从另一个角度解释一下。
公平地说,bc它具有优势,因为它不必从磁盘读取任何内容,只需要它的 blob/二进制文件,而 python 必须导入一系列模块 + 读取文件。所以你的测试可能偏向于bc. 要实际测试它,您应该使用bc -q filewhere filecontains:
6^6^6
quit
Run Code Online (Sandbox Code Playgroud)
更改只是修改了使用时间echo:
bc 0.33s user 0.00s system 80% cpu 0.414 total
Run Code Online (Sandbox Code Playgroud)
使用文件:
bc -q some 0.33s user 0.00s system 86% cpu 0.385 total
Run Code Online (Sandbox Code Playgroud)
(您将不得不使用 terdon 的方法来注意到更大的差异,但至少我们知道它们是)
现在,从python的角度来看,python每次都需要从磁盘中读取、编译和执行文件,加上像安德鲁点那样加载模块,这使得执行时间变慢。如果您编译 python 脚本的字节码,您会注意到执行代码所需的总时间减少了 50%:
python some.py > /dev/null 0.25s user 0.01s system 63% cpu 0.413 total
Run Code Online (Sandbox Code Playgroud)
编译:
./some.pyc 0.22s user 0.00s system 77% cpu 0.282 total
Run Code Online (Sandbox Code Playgroud)
如您所见,有几个因素会影响不同工具之间的时间执行。
| 归档时间: |
|
| 查看次数: |
3292 次 |
| 最近记录: |