Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在加载库时加速python启动和/或减少文件搜索?_Python_Startup - Fatal编程技术网

如何在加载库时加速python启动和/或减少文件搜索?

如何在加载库时加速python启动和/或减少文件搜索?,python,startup,Python,Startup,我有一个由多用户环境中用python编写的不同工具组成的框架 第一次登录系统并启动一个命令时,仅显示几行帮助就需要6秒钟。如果我立即再次发出相同的命令,则需要0.1秒。几分钟后回到6秒。(短寿命缓存的证明) 系统位于GPFS上,因此磁盘吞吐量应该是正常的,尽管由于系统中的文件量,访问可能较低 strace -e open python tool | wc -l 显示启动工具时访问的2154个文件 strace -e open python tool | grep ENOENT | wc -l

我有一个由多用户环境中用python编写的不同工具组成的框架

第一次登录系统并启动一个命令时,仅显示几行帮助就需要6秒钟。如果我立即再次发出相同的命令,则需要0.1秒。几分钟后回到6秒。(短寿命缓存的证明)

系统位于GPFS上,因此磁盘吞吐量应该是正常的,尽管由于系统中的文件量,访问可能较低

strace -e open python tool | wc -l
显示启动工具时访问的2154个文件

strace -e open python tool | grep ENOENT | wc -l
显示正在查找的1945个丢失的文件。(一个非常糟糕的命中率是你问我:-)

我有一种预感,加载该工具所花费的过多时间是通过查询GPFS中的所有文件来消耗的,这些文件会被缓存以供下次调用(在系统或GPFS级别),尽管我不知道如何测试/证明它。 我没有系统的根访问权限,只能向GPFS和/tmp写入

是否有可能改进python对丢失文件的搜索

你知道如何用一种简单的方法来测试吗? (在/tmp上重新安装所有东西并不简单,因为涉及到许多软件包,virtualenv也不会有帮助(我认为),因为它只是链接gpfs系统上的文件)

当然,一种选择是使用一个分叉的守护进程,但这远不是“简单”的,而且是最后的解决方案


感谢阅读。

Python 2首先查找相对于当前包的模块。如果您的库代码有许多顶级模块的导入,那么这些模块都会首先作为相对模块进行查找。因此,如果包
foo.bar
import
os
,那么Python首先查找
foo/bar/os.py
。Python本身也会缓存此未命中

在Python3中,默认值改为绝对导入;您可以切换Python 2.5及更高版本,以使用每个模块的绝对导入:

文件查找未命中的另一个来源是加载
.pyc
字节码缓存文件;如果由于某种原因(当前Python进程的文件系统不可写)丢失了这些文件,那么Python将继续在每次运行中查找这些文件。您可以使用以下方法创建这些缓存:


如果您以正确的写入权限运行该模块。

使用imp模块如何?特别是有一个功能: imp.find_模块(模块,路径)在此处

至少这个例子(见下文)减少了open()系统调用的数量,而不是简单的“import numpy,scipy”:(更新:但看起来不可能通过这种方式显著减少系统调用…)


我想你最好检查一下PYTHONPATH是空的还是小的,因为这也会增加加载时间

嗯。。。我在顶层调用中尝试了这个方法(脚本导入其余部分),但它只添加了另外25个文件查找,用于搜索未来,没有任何其他好处:-/。所有的.pyc都存在,但搜索顺序始终是:
*.so->*module.so->*.py->*.pyc
,所以没有区别。顺便说一下,这是绝对的进口(无)。无论如何谢谢你!更正。是的,我想Python必须在Python文件之前查找C扩展名,并且必须找到
.py
文件来测试
.pyc
文件是否过时。我想给你一些可以避免的查找选项。真的,谢谢你!我还用一个只加载操作系统的文件对它进行了测试,在测试之前,打开
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
选项并没有什么区别。我想我可以尝试调优PYTHONPATH,尽管我希望有一种方法可以缓存从一个python调用到另一个python调用的所有调用。。。是否可以从给定路径将模块加载到内存中?也许我可以预加载它们…@estani:一旦导入成功,导入的文件就不会再次加载。不过,在将文件导入主脚本的那一刻移动并不会减少启动时间,而是告诉python我要为每个模块加载哪个文件。因此,我可以使用strace缓存这些文件的位置,然后使用类似于
imp.module\u load
的方法加载它们。我会利用我关于这些文件位置的知识来加快速度。。。但这不会太多,因为大多数模块已经在python启动时加载(如os、sys等)……事实上,我尝试了这个,看起来很有希望,尽管所有默认库都在启动时运行,我不能告诉python应该从哪个文件加载模块,但让它在目录中搜索它,导致4 open()呼叫和至少2次未命中。我只是希望有一种方法告诉python不要这样做。
from __future__ import absolute_import
python -m compileall /path/to/directory/with/pythoncode
import imp
import sys


def loadm(name, path):
    fp, pathname, description = imp.find_module(name,[path])
    try:
        _module = imp.load_module(name, fp, pathname, description)
        return _module
    finally:
        # Since we may exit via an exception, close fp explicitly.
        if fp:
            fp.close()


numpy = loadm("numpy", "/home/username/py-virtual27/lib/python2.7/site-packages/")
scipy = loadm("scipy", "/home/username/py-virtual27/lib/python2.7/site-packages/")