之前曾询问过如何加快导入Python模块的问题(Speeding up the python "import" loader和Python -- Speed Up Imports?),但没有具体的例子,也没有提供可接受的解决方案。因此,我将在这里再次讨论这个问题,但这次是一个具体的例子。
我有一个Python脚本,可以从磁盘加载三维图像堆栈,平滑它,并将其显示为电影。当我想快速查看我的数据时,我从系统命令提示符调用此脚本。我可以用700毫秒来平滑数据,因为这与MATLAB相当。但是,导入模块需要额外的650 ms。因此,从用户的角度来看,Python代码的运行速度只有其一半。
这是我正在导入的一系列模块:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import scipy.ndimage
import scipy.signal
import sys
import os
当然,并非所有模块的导入速度都相同。罪魁祸首是:
matplotlib.pyplot [300ms]
numpy [110ms]
scipy.signal [200ms]
我已尝试使用from
,但这并不快。由于Matplotlib是主要的罪魁祸首,它因缓慢的屏幕更新而闻名,我寻找替代方案。一个是PyQtGraph,但导入需要550毫秒。
我知道一个明显的解决方案,即从交互式Python会话而不是系统命令提示符调用我的函数。这很好但是它太像MATLAB了,我更喜欢从系统提示中获得我的功能的优雅。
我是Python的新手,我不知道如何继续这一点。由于我是新手,我很欣赏有关如何实施建议解决方案的链接。理想情况下,我正在寻找一个简单的解决方案(不是我们所有人!),因为代码需要在多台Mac和Linux机器之间移植。
答案 0 :(得分:11)
你可以构建一个简单的服务器/客户端,服务器不断运行并更新绘图,客户端只是传递下一个要处理的文件。
我根据socket
模块文档中的基本示例编写了一个简单的服务器/客户端示例:http://docs.python.org/2/library/socket.html#example
这是server.py:
# expensive imports
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import scipy.ndimage
import scipy.signal
import sys
import os
# Echo server program
import socket
HOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
while 1:
conn, addr = s.accept()
print 'Connected by', addr
data = conn.recv(1024)
if not data: break
conn.sendall("PLOTTING:" + data)
# update plot
conn.close()
和client.py:
# Echo client program
import socket
import sys
HOST = '' # The remote host
PORT = 50007 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(sys.argv[1])
data = s.recv(1024)
s.close()
print 'Received', repr(data)
您只需运行服务器:
python server.py
执行导入,然后客户端只通过套接字将新文件的文件名发送到plot:
python client.py mytextfile.txt
然后服务器更新图。
在我的机器上运行导入需要0.6秒,同时运行client.py
0.03秒。
答案 1 :(得分:8)
不是该问题的实际答案,而是有关如何使用Python 3.7和tuna(我的一个小项目)来描述导入速度的提示:
python3.7 -X importtime -c "import scipy" 2> scipy.log
tuna scipy.log
答案 2 :(得分:3)
您可以使用imp
手动导入模块。请参阅documentation here。
例如,import numpy as np
可能写成
import imp
np = imp.load_module("numpy",None,"/usr/lib/python2.7/dist-packages/numpy",('','',5))
这将使python无法浏览整个sys.path
以找到所需的包。
另见:
答案 3 :(得分:0)
1.35秒并不长,但我想如果你已经习惯了一半用于快速检查"那也许就好了。
Andrea建议使用简单的客户端/服务器设置,但在我看来,您可以轻松地调用脚本进行非常轻微的修改,并在工作时保持其控制台窗口打开:
我假设您的脚本每次都是相同的,即您不需要每次都给它图像堆栈位置或任何特定命令(但这些也很容易!)。
示例RAAC' s_Script.py:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import scipy.ndimage
import scipy.signal
import sys
import os
print('********* RAAC\'s Script Now Running *********')
while True: # Loops forever
# Display a message and wait for user to enter text followed by enter key.
# In this case, we're not expecting any text at all and if there is any it's ignored
input('Press Enter to test image stack...')
'''
*
*
**RAAC's Code Goes Here** (Make sure it's indented/inside the while loop!)
*
*
'''
要结束脚本,请关闭控制台窗口或按ctrl + c。
我已经尽可能地简化了这一点,但是只需要很少的额外工作来处理好的事情,根据输入做一些稍微不同的事情等等。