Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.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 为什么显式调用os.mkdir()时速度较慢?_Python_Linux_Python 2.7_Operating System - Fatal编程技术网

Python 为什么显式调用os.mkdir()时速度较慢?

Python 为什么显式调用os.mkdir()时速度较慢?,python,linux,python-2.7,operating-system,Python,Linux,Python 2.7,Operating System,我一直在做一个项目,它必须创建一个大的目录结构。我的第一个解决方案是保留所有存在的dir的dict,如果遇到一个尚未使用的dir,则使用os.makedirs()创建它和任何缺少的中介。 当我分析这段代码时,我发现大部分时间(132秒中的105秒)都花在调用posix.stat()以确定中间目录不存在上。然而,我正在一个空目录中构建整个结构,所以我已经知道中间目录都不存在 为了充分利用这一点,我编写了一个版本的代码,其中保存了描述目录树结构的内部备忘录,以便在不查询操作系统的情况下确定创建了哪些

我一直在做一个项目,它必须创建一个大的目录结构。我的第一个解决方案是保留所有存在的dir的dict,如果遇到一个尚未使用的dir,则使用os.makedirs()创建它和任何缺少的中介。 当我分析这段代码时,我发现大部分时间(132秒中的105秒)都花在调用posix.stat()以确定中间目录不存在上。然而,我正在一个空目录中构建整个结构,所以我已经知道中间目录都不存在

为了充分利用这一点,我编写了一个版本的代码,其中保存了描述目录树结构的内部备忘录,以便在不查询操作系统的情况下确定创建了哪些目录:

class DirTree:
  def __init__(self, root):
    self.root = os.path.abspath(root)
    self.tree = {}
  def makedirs(self, path):
    relpath = os.path.relpath(path, self.root).replace('\\', '/')
    built = self.root
    node = self.tree
    for directory in relpath.split('/'):
        built = os.path.join(built, directory)
        if directory in node:
            node = node[directory]
        else:
            node[directory] = {}
            node = node[directory]
            os.mkdir(built, 0777)
这段代码确实运行得更快,但是当我通过探查器运行它时,对os.mkdir()的相同4068调用现在需要4倍的时间(94秒而不是24秒)。它不理解为什么从my函数调用此函数比由os.makedirs()调用此函数花费的时间更长。
有人知道为什么吗?

os.mkdirs在创建目录之前检查路径组件的存在是正确的。您的代码和os.mkdir都使用c-python模块来实际实现mkdir,在linux上解析为系统调用mkdir

看起来os.mkdir真的不需要统计,因为统计非常耗时,因为如果“a”不存在,那么“a/b”肯定也不存在

使用它可以看出,两种实现调用mkdir的次数相同,但是当路径是相对路径时,您创建的函数无论如何都会构造绝对路径,而os.mkdirs使用相对路径

一种可能性是,额外的时间是操作系统在目录结构中搜索以找到正确的目录,而不是每次都添加到“”

os.mkdirs

stat("a/b/c", 0x7fff34b1c4d0)           = -1 ENOENT (No such file or directory)
stat("a/b", 0x7fff34b1c260)             = -1 ENOENT (No such file or directory)
stat("a", 0x7fff34b1bff0)               = -1 ENOENT (No such file or directory)
mkdir("a", 0777)                        = 0
mkdir("a/b", 0777)                      = 0
mkdir("a/b/c", 0777)                    = 0
mkdir("a/b/c/d", 0777)                  = 0
 4003    0.132    0.000    0.132    0.000 {posix.mkdir}
改进的mkdirs

mkdir("/tmp/a", 0777)                   = 0
mkdir("/tmp/a/b", 0777)                 = 0
mkdir("/tmp/a/b/c", 0777)               = 0
mkdir("/tmp/a/b/c/d", 0777)             = 0
 4003    0.147    0.000    0.147    0.000 {posix.mkdir}
尽管如此,我无法复制你的结果。我发现os.mkdirs或您的源代码调用mkdir(使用cProfile)所花费的时间大致相同

os.mkdirs

stat("a/b/c", 0x7fff34b1c4d0)           = -1 ENOENT (No such file or directory)
stat("a/b", 0x7fff34b1c260)             = -1 ENOENT (No such file or directory)
stat("a", 0x7fff34b1bff0)               = -1 ENOENT (No such file or directory)
mkdir("a", 0777)                        = 0
mkdir("a/b", 0777)                      = 0
mkdir("a/b/c", 0777)                    = 0
mkdir("a/b/c/d", 0777)                  = 0
 4003    0.132    0.000    0.132    0.000 {posix.mkdir}
改进的mkdirs

mkdir("/tmp/a", 0777)                   = 0
mkdir("/tmp/a/b", 0777)                 = 0
mkdir("/tmp/a/b/c", 0777)               = 0
mkdir("/tmp/a/b/c/d", 0777)             = 0
 4003    0.147    0.000    0.147    0.000 {posix.mkdir}
但是,在posixpath中的新源代码中花费了大量时间

 4000    0.104    0.000    1.003    0.000 posixpath.py:400(relpath)

也许这是一个人工制品的方法,以概况或微妙的安装。

我不认为这是在C端。如果head和tail而不是path.exists(head):在
makedirs()
中执行
stat()
调用,则它似乎是