[英]How to improve python import speed?
在SO上已經多次問過這個問題(例如here ),但是還沒有真正的答案。
我正在寫一個簡短的命令行工具來渲染模板。 它是使用Makefile固定的:
i = $(wildcard *.in)
o = $(patsubst %.in, %.out, $(t))
all: $(o)
%.out: %.in
./script.py -o $@ $<
在此虛擬示例中,Makefile解析每個.in
文件以生成.out
文件。 對我來說,使用make
非常方便,因為在此腳本前后,我還有許多其他操作要觸發。 此外,我想保持盡可能的吻 。
因此,我想使我的工具保持簡單,愚蠢並使用語法
script -o out in
分別處理每個文件script -o out in
我的腳本使用以下內容:
#!/usr/bin/env python
from jinja2 import Template, nodes
from jinja2.ext import Extension
import hiyapyco
import argparse
import re
...
問題在於每次執行要花費我大約1.2秒的時間(大約60毫秒用於處理,大約1140毫秒用於import指令):
$ time ./script.py -o foo.out foo.in
real 0m1.625s
user 0m0.452s
sys 0m1.185s
我的100個文件的Makefile的整體執行是荒謬的:〜100個文件x 1.2s = 120s。
這不是解決方案,但應該是解決方案。
我可以使用什么替代方法?
編輯
我喜歡Python,因為它的語法易讀並且具有社區規模。 在這種特殊情況下(命令行工具),我不得不承認Perl仍然是不錯的選擇。 用Perl(也是一種解釋語言)編寫的相同腳本快了大約12倍(使用Text::Xslate
)。
無論如何,我都不想推廣Perl,我只是想解決Python的最大問題:由於導入時間很短,它還不適合用於簡單的命令行工具。
這並不是一件容易的事,但是您可以將程序變成一個位於后台並處理命令以處理文件的程序。
另一個程序可以向其提供處理命令,從而使真正的開始變得非常容易。
將模板部分作為一個單獨的過程編寫。 第一次運行“ script.py”將啟動該單獨的過程。 該過程一旦存在,便可以通過命名管道將輸入/輸出文件名傳遞給它。 如果該進程在x秒鍾內沒有任何輸入,它將自動退出。 x的大小取決於您的需求
因此,通過script.py寫入命名管道將參數傳遞給長時間運行的過程。 導入僅發生一次(假設輸入相當頻繁),並且正如BPL指出的那樣,這將使一切運行得更快
您可以使用glob
對所需的文件執行該操作。
import glob
in_files=glob.glob('*.in')
out_files=glob.glob('*.out')
因此,您可以在同一腳本中處理所有文件,而不是每次對每對文件都調用腳本。 至少這樣,您不必每次都啟動python。
問題出在哪里似乎很清楚,現在您得到了:
cost(file) = 1.2s = 60ms + 1040ms
,這意味着:
cost(N*files) = N*1.2s
現在,為什么不將其更改為:
cost1(files) = 1040ms + N*60ms
這樣,理論上處理100個文件將是7,04s而不是120s
編輯:
因為我對此問題不滿意,所以我舉一個小例子,假設您有這個python文件:
# foo.py
import numpy
import cv2
print sys.argv[0]
現在,在我的盒子上,執行時間為1.3秒:
for /l %x in (1, 1, 100) do python foo.py
我將獲得100 * 1.3s的執行時間,我的建議是將foo.py變成這樣:
import numpy
import cv2
def whatever_rendering_you_want_to_do(file):
pass
for file in sys.argv:
whatever_rendering_you_want_to_do(file)
這樣一來,您只需導入一次,而不是100次
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.