NamedTemporaryFile速度令人印象深刻

时间:2016-12-12 14:46:42

标签: python subprocess

我尝试使用NamedTemporaryFile并将此对象传递给要使用的外部程序,然后使用Popen收集输出。我希望这比在硬盘上创建真实文件更快,并避免尽可能多的IO。我创建的临时文件的大小很小,大约为KB左右,我发现创建一个临时文件比使用普通文件读取/写入要慢。我在这里缺少一个技巧吗?当我使用NamedTemporaryFile时,幕后发生了什么?

# Using named temp file
with tempfile.NamedTemporaryFile(delete=False) as temp:  # delete=False to keep a reference to the file for process calls
    for idx, item in enumerate(r):
        temp.write(">{}\n{}\n".format(idx, item[1]))
>>> 8.435 ms

# Using normal file io
with open("test.fa", "w") as temp:
    for idx, item in enumerate(r):
        temp.write(">{}\n{}\n".format(idx, item[1]))
>>> 0.506 ms

#--------

# Read using temp file
[i for i in open(name, "r")]
>>> 1.167 ms

[i for i in open("test.fa", "r")]
>>> 0.765 ms

进行一些分析似乎几乎整个时间花在创建临时对象上。在此示例中使用tempfile.NamedTemporaryFile(delete=False)需要8毫秒

1 个答案:

答案 0 :(得分:2)

虽然我对Python运行时效率不是很有经验,但我会尝试回答你的问题。

在Python tempfile.py的代码中钻取,你可以找到关于可能需要一些时间的线索的线索。 _mkstemp_inner函数可能会打开一些文件并为每个文件引发异常。目录包含的临时文件越多,获得的文件名冲突就越多,所需的时间就越长。尝试清空临时目录。

def _mkstemp_inner(dir, pre, suf, flags):
    """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile."""

    names = _get_candidate_names()

    for seq in range(TMP_MAX):
        name = next(names)
        file = _os.path.join(dir, pre + name + suf)
        try:
            fd = _os.open(file, flags, 0o600)
            _set_cloexec(fd)
            return (fd, _os.path.abspath(file))
        except OSError as e:
            if e.errno == _errno.EEXIST:
                continue # try again
            raise

    raise IOError(_errno.EEXIST, "No usable temporary file name found")

希望有所帮助。