7

我有一个由多用户环境中用 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 级别),尽管我不知道如何测试/证明给我看。我没有系统的 root 访问权限,只能写入 GPFS 和 /tmp。

有可能改善这一点python quest for missing files吗?

关于如何以简单的方式进行测试的任何想法?(在 /tmp 上重新安装所有内容并不简单,因为涉及到许多软件包,virtualenv 也无济于事(我认为),因为它只是链接 gpfs​​ 系统上的文件)。

一个选项当然是拥有一个分叉的守护进程,但这远非“简单”,而是最后的解决方案。

谢谢阅读。

4

2 回答 2

2

使用 imp 模块怎么样?特别是这里有一个函数:imp.find_module(module, path) http://docs.python.org/2.7/library/imp.html

至少这个例子(见下文)减少了 open() 系统调用的数量与简单的 'import numpy,scipy' 相比:(更新:但看起来不可能以这种方式显着减少系统调用......)

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/")

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

于 2013-03-18T17:28:11.987 回答
2

Python 2 首先查找相对于当前包的模块。如果您的库代码对许多顶级模块有很多导入,那么这些模块都会首先被查找为相对。所以,如果包foo.barimport os,那么 Python首先寻找foo/bar/os.py. Python 本身也缓存了这个未命中。

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

from __future__ import absolute_import

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

python -m compileall /path/to/directory/with/pythoncode

前提是您以正确的写入权限运行它。

于 2013-03-18T10:23:44.463 回答