Skip to main content
 首页 » 编程设计

大数据 os.path.getsize 上的 Python 代码性能

2025年01月19日23davidwang456

下面是我按升序获取文件大小的代码。

def Create_Files_Structure(directoryname): 
   for path, subdirs, files in os.walk(directoryname,followlinks=False): 
        subdirs[:] = [d for d in subdirs if not d[0] == '.'] 
        try: 
           files_list.extend([(os.path.join(path, file),os.path.getsize(os.path.join(path, file))) for file in files ]) 
        except Exception as e: 
            print() 
   files_list.sort(key=lambda s: s[1], reverse=True) 
   for pair in files_list: 
     print(pair) 
   print(len(files_list)) 
 
start=time.time() 
Create_Files_Structure("/home/<username>") 
end=time.time() 
print(end-start) 

此代码有效,但如果目录大小​​以 TB 或 PB 为单位,性能会很慢。请提出任何改进代码以获得更快结果的建议。

请您参考如下方法:

  1. 要感受一下您能获得多快,请尝试在目录上运行 du -k 并计时。对于完整列表,您可能不会比使用 Python 更快。
  2. 如果您在 Python < 3.5 上运行,请尝试升级或使用 scandir以获得不错的性能改进。
  3. 如果您真的不需要整个文件列表但可以接受最大的 1000 个文件:

避免保留列表并使用 heapq.nlargest带发电机

def get_sizes(root): 
  for path, dirs, files in os.walk(root): 
    dirs[:] = [d for d in dirs if not d.startswith('.')] 
    for file in files: 
        full_path = os.path.join(path, file) 
        try: 
          # keeping the size first means no need for a key function 
          # which can affect performance 
          yield (os.path.getsize(full_path), full_path) 
        except Exception: 
          pass 
 
import heapq 
for (size, name) in heapq.nlargest(1000, get_sizes(r"c:\some\path")): 
  print(name, size) 

编辑 - 为了在 Windows 上变得更快 - os.scandir 生成已经包含有助于避免另一个系统调用的大小的条目。

这意味着使用 os.scandir 并自己递归,而不是依赖 os.walk,后者不会产生该信息。

在 scandir PEP 471 中有一个类似的工作示例 get_tree_size() 函数可以轻松修改以生成名称和大小。每个条目的大小都可以通过 entry.stat(follow_symlinks=False).st_size 访问。