You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Linux下海量文件指定创建时段筛选的Python代码优化问询

提升大目录文件时段筛选速度的优化方案

我来分享几个能显著提升你这段代码运行速度的方法,尤其是在处理数千个文件的大目录时:

1. 用os.scandir替代os.listdir+os.path.getctime(性能提升核心)

这是最有效的优化点!os.listdir只会返回文件名,之后你需要对每个文件单独调用os.path.getctime获取时间——这意味着每个文件都要发起一次系统调用,文件越多,开销越大。

os.scandir(Python 3.5+支持)会一次性获取目录下所有文件的元数据(包括时间信息),利用了系统底层的getdents调用,大幅减少系统调用次数,速度能提升数倍。它返回的DirEntry对象可以直接通过stat()获取文件时间,无需额外调用。

2. 提前转换时间范围为时间戳,避免重复类型转换

原代码中每次都把文件时间戳转成datetime对象再和date_start/date_end比较,这会产生额外的类型转换开销。我们可以先把date_startdate_end转成时间戳,直接和文件的时间戳比较,跳过datetime转换步骤。

3. 消除冗余的目录遍历

你的代码里先执行了files = os.listdir(ARCHIVE_FOLDER),之后又循环os.listdir(ARCHIVE_FOLDER)——这是完全冗余的,直接遍历一次即可,避免重复读取目录内容。

优化后的完整代码

from datetime import datetime, timedelta
import os

def get_time():
    tmp_date = datetime.now()
    year = tmp_date.year
    month = tmp_date.month
    day = tmp_date.day
    date_start = datetime(year, month, day, 7,30)
    date_end = datetime(year, month, day, 19,30)
    shift = "Day Shift"
    
    if date_start < tmp_date < date_end:
        # 当前是白班时段,筛选白班文件
        pass
    else:
        # 当前是夜班时段,筛选夜班文件(跨天)
        if tmp_date < date_start:
            # 当前在凌晨7:30前,筛选前一天19:30到当天7:30的文件
            date_start = datetime(year, month, day, 19,30) - timedelta(1)
            date_end = datetime(year, month, day, 7,30)
        else:
            # 当前在19:30后,筛选当天19:30到次日7:30的文件
            date_start = datetime(year, month, day, 19,30)
            date_end = datetime(year, month, day, 7,30) + timedelta(1)
        shift = "Night Shift"
    
    # 转换为时间戳,方便后续比较
    return date_start.timestamp(), date_end.timestamp(), shift

def get_qc_success(ROOT_FOLDER):
    start_ts, end_ts, shift = get_time()
    files = []
    ARCHIVE_FOLDER = os.path.join(ROOT_FOLDER,"LOMS","ARCHIVE")
    
    # 使用os.scandir遍历目录,一次性获取元数据
    with os.scandir(ARCHIVE_FOLDER) as entries:
        for entry in entries:
            # 只处理文件,跳过目录
            if entry.is_file():
                # 获取文件状态改变时间戳(Linux下st_ctime是状态改变时间,若需创建时间可尝试st_birthtime)
                file_ctime_ts = entry.stat().st_ctime
                if start_ts < file_ctime_ts < end_ts:
                    files.append(entry.name)
    
    len_success = len(files)
    return files, len_success, shift

额外说明

  • 关于Linux下的文件创建时间:Linux默认的st_ctime是文件状态改变时间(比如权限修改、内容修改都会更新),如果你的需求是严格的文件创建时间,可以尝试entry.stat().st_birthtime,但这个字段依赖文件系统支持(比如ext4支持,部分老文件系统不支持)。
  • 内存优化os.scandir返回的是迭代器,不会一次性把所有文件信息加载到内存,即使目录有几万个文件,内存占用也很低。

内容的提问来源于stack exchange,提问作者Royal

火山引擎 最新活动