gpt4 book ai didi

python - 为什么 os.scandir() 和 os.listdir() 一样慢?

转载 作者:行者123 更新时间:2023-12-03 11:06:43 27 4
gpt4 key购买 nike

我尝试在 Windows 上使用 os.scandir() 而不是 os.listdir() 来优化用 Python 编写的文件浏览功能。但是,时间保持不变,大约2分半钟,我不知道为什么。
以下是原始和修改的功能:

os.listdir() 版本:

def browse(self, path, tree):
# for each entry in the path
for entry in os.listdir(path):
entity_path = os.path.join(path, entry)
# check if support by git or not
if self.git_ignore(entity_path) is False:
# if is a dir create a new level in the tree
if os.path.isdir( entity_path ):
tree[entry] = Folder(entry)
self.browse(entity_path, tree[entry])
# if is a file add it to the tree
if os.path.isfile(entity_path):
tree[entry] = File(entity_path)

os.scandir() 版本:
def browse(self, path, tree):
# for each entry in the path
for dirEntry in os.scandir(path):
entry_path = dirEntry.name
entity_path = dirEntry.path
# check if support by git or not
if self.git_ignore(entity_path) is False:
# if is a dir create a new level in the tree
if dirEntry.is_dir(follow_symlinks=True):
tree[entry_path] = Folder(entity_path)
self.browse(entity_path, tree[entry_path])
# if is a file add it to the tree
if dirEntry.is_file(follow_symlinks=True):
tree[entry_path] = File(entity_path)

此外,这里是其中使用的辅助功能:
def git_ignore(self, filepath):
if '.git' in filepath:
return True
if '.ci' in filepath:
return True
if '.delivery' in filepath:
return True
child = subprocess.Popen(['git', 'check-ignore', str(filepath)],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
output = child.communicate()[0]
status = child.wait()
return status == 0

============================================================

class Folder(dict):
def __init__(self, path):
self.path = path
self.categories = {}

============================================================

class File(object):
def __init__(self, path):
self.path = path
self.filename, self.extension = os.path.splitext(self.path)

有没有人可以解决如何使函数运行得更快的解决方案?我的假设是在开始时提取名称和路径使它运行得比它应该的慢,这是正确的吗?

最佳答案

关于你的问题:
os.walk 似乎调用 stats 的次数超过了必要的次数。这似乎是它比 os.scandir() 慢的原因。
在这种情况下,我认为提高速度性能的最佳方法是
使用并行处理,在某些循环中可以令人难以置信地提高速度。
关于这个问题有很多帖子。这里一:
Parallel Processing in Python – A Practical Guide with Examples .

尽管如此,我还是想分享一些关于它的想法。
我也一直在想什么是最佳用法这三个选项(scandir、listdir、walk)。关于性能比较的文档并不多。可能最好的方法是像你一样自己测试它。这是我的结论:
os.listdir() 的用法:
与 os.scandir() 相比,它似乎没有优势,只是更容易理解。当我只需要列出目录中的文件时,我仍然使用它。
优点:

  • 快速简单

  • 缺点:
  • 太简单了,仅适用于列出目录中的文件和目录,因此您可能需要将其与其他方法结合使用以获得有关文件元数据的额外功能。如果是这样,最好使用 os.scandir()。

  • os.walk() 的用法:
    当我们需要获取目录(和子目录)中的所有项目时,这是最常用的函数。
    优点:
  • 这可能是遍历所有项目路径和名称的最简单方法。

  • 缺点:
  • 似乎调用 stats 的次数比必要的要多。这似乎是它比 os.scandir() 慢的原因。
  • 尽管它为您提供了文件的根部分,但它不提供 os.scandir() 的额外元信息。

  • os.scandir() 的用法:
    它似乎(几乎)两全其美。它为您提供简单的速度 os.listdir 具有额外的功能,可以让您
    简化您的循环,因为您可以避免使用 exiftool 或其他元数据工具
    当您需要有关文件的额外信息时。
    优点:
  • 快速地。与 os.listdir() 速度相同
  • 非常好的附加功能。

  • 缺点:
  • 如果你想深入研究子文件,你需要创建另一个函数来扫描每个子目录。这个函数非常简单,但在这种情况下使用 os.walk 可能会更 Pythonic(我只是指更优雅的语法)。

  • 这就是我阅读并使用它们后的看法。我很高兴得到纠正,所以我可以了解更多。

    关于python - 为什么 os.scandir() 和 os.listdir() 一样慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59268696/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com