加快Python命令行应用的初始执行速度
我用Python和argparse做了一个命令行应用,主要用来快速记笔记。现在这个程序基本上就是打开Vim,然后把内容存到一个SQLite数据库里。
问题是,在我的两台电脑上,加载Python的速度非常慢(大约是2/3GHz的Intel Core 2 Duo),最基本的功能(启动时打印帮助菜单)都要花超过一秒钟。我知道我的代码没问题,因为一旦Python加载完,运行起来就很快,但我用一个简单的Hello World程序也能感受到这种烦恼:
$ time python -c "print 'hello world'"
hello world
real 0m0.669s
user 0m0.070s
sys 0m0.041s
当然,这个问题并不是Python特有的:
$ time erl -noshell -eval 'io:fwrite("Hello, World!\n"), init:stop().'
Hello, World!
real 0m2.824s
user 0m0.253s
sys 0m0.104s
我想问的是:如何能加快Python应用程序的初始执行速度? 我希望我的程序能像git
或wc
那样快速。
系统:我在OS X 10.6.8上用python2.6和在OS X 10.7.2上用python2.7时都遇到这个问题。
注意:后续执行python
(和erl
)的速度要快得多,但我已经在使用这个程序了,我希望它能真正快速。
更新:我尝试了运行pypy,发现它的初始加载时间和python2.6和2.7在我的两台系统上差不多(初始加载大约0.5秒),后续调用的性能比在OS X 10.6.8上的python2.6慢了一半(pypy大约0.08秒,2.6大约0.35秒),在OS X 10.7.2上与python2.7的后续调用性能相似(pypy和python2.7都是大约0.08秒)。
更新2:根据dr jimbob的建议得到的输出(这似乎把初始加载时间缩短了三分之二) -
$ python -vSEc "print 'hello world'"
# installing zipimport hook
import zipimport # builtin
# installed zipimport hook
import encodings # directory /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings
# /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings/__init__.pyc matches /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings/__init__.py
import encodings # precompiled from /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings/__init__.pyc
# /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/codecs.pyc matches /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/codecs.py
import codecs # precompiled from /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/codecs.pyc
import _codecs # builtin
# /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings/aliases.pyc matches /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings/aliases.py
import encodings.aliases # precompiled from /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings/aliases.pyc
# /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings/utf_8.pyc matches /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings/utf_8.py
import encodings.utf_8 # precompiled from /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/encodings/utf_8.pyc
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
hello world
# clear __builtin__._
# clear sys.path
# clear sys.argv
# clear sys.ps1
# clear sys.ps2
# clear sys.exitfunc
# clear sys.exc_type
# clear sys.exc_value
# clear sys.exc_traceback
# clear sys.last_type
# clear sys.last_value
# clear sys.last_traceback
# clear sys.path_hooks
# clear sys.path_importer_cache
# clear sys.meta_path
# clear sys.flags
# clear sys.float_info
# restore sys.stdin
# restore sys.stdout
# restore sys.stderr
# cleanup __main__
# cleanup[1] zipimport
# cleanup[1] _codecs
# cleanup[1] signal
# cleanup[1] encodings
# cleanup[1] encodings.utf_8
# cleanup[1] encodings.aliases
# cleanup[1] exceptions
# cleanup[1] _warnings
# cleanup[1] codecs
# cleanup sys
# cleanup __builtin__
# cleanup ints: 3 unfreed ints
# cleanup floats
real 0m0.267s
user 0m0.009s
sys 0m0.043s
1 个回答
你可以使用一种类似于“微软Office快速入门”或“Java快速入门”的技巧,记得还有“Adobe快什么”的方法...
这个窍门就是尽量让程序的所有库文件一直保存在磁盘缓存中。
你可以用一个简单的定时任务命令来实现,每小时运行一次。具体的设置会根据你的系统有所不同,但可以用类似下面的命令:
$ crontab -e
0 * * * * python -c 'pass'
不过我觉得更有效的方法是写一个简单的Python脚本,导入你程序使用的所有模块,然后就结束。