You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多目录图片获取Groovy代码优化请求:缩减列表提升大文件处理效率

问题描述

场景与用例

  • 存储结构:按不同大小分类的文件夹存储图片,每个大小文件夹下包含CX/MX/VX目录;每个这类目录下有SER00001等系列子目录,图片存放在这些系列子目录中。
  • 用例流程:
    1. 随机选择一个大小分类目录(如5MB、30MB、1GB);
    2. 该目录下存在CX/MX/VX类型目录;
    3. 每个类型目录下包含系列子目录;
    4. 系列子目录内存储图片;
    5. 按All/Single规则遍历图片:
      • All:遍历所有CX/MX/VX目录下的所有图片;
      • Single:仅遍历其中一个CX/MX/VX目录下的所有图片。

现有Groovy代码可正常运行,但因定义过多冗余中间列表,处理大量图片时IO与内存开销过大,响应耗时过长,需优化性能。

原代码:

import groovy.io.FileType;
def dir = new File(vars.get("dirName"));
def selectionPattern = ["All","Single"];
def list = [];
def listNew = [];
def list_series = [];
def list_images = [];
def modalityDir = [];
def modalityFileName = [];
def finalModalityName = [];
def rnd = new Random();
def rndSelect = new Random();
def userSelectionForModalityFolder = selectionPattern[rndSelect.nextInt(selectionPattern.size())];

if (userSelectionForModalityFolder === "All") {
    dir.eachDir() {
        dirList ->
        list << dirList
    }
    def randomParentDirectorySelected = list[rnd.nextInt(list.size())];
    randomParentDirectorySelected.eachDir() {
        listDir ->
        list_series << listDir
    }
    for (allSelectionDir in list_series) {
        allSelectionDir.eachDir() {
            allSelectDirectory ->
            list_images << allSelectDirectory
        }
    }
    for (int b = 0; b < list_images.size(); b++) {
        File[] modalityFiles = list_images[b].listFiles();
        modalityFileName << modalityFiles
    }
    for (int n = 0; n < modalityFileName.size(); n++) {
        for (int p = 0; p < modalityFileName[n].size(); p++) {
            finalModalityName << modalityFileName[n][p]
        }
    }
    vars.putObject("All_Modality",finalModalityName);
} else {
    dir.eachDir() {
        dirList ->
        list << dirList
    }
    def randomParentDirectorySelected = list[rnd.nextInt(list.size())]
    randomParentDirectorySelected.eachDir() {
        secDirList ->
        listNew << secDirList
    }
    if (listNew.size() > 2) {
        def totalFile = ranSelect.nextInt(listNew.size());
    } else {
        Random ranSelect = new Random();
        def totalFile = ranSelect.nextInt(listNew.size() + 4);
        def random_ModalitySelection = listNew[rnd.nextInt(listNew.size())]
        random_ModalitySelection.eachDir() {
            modalityD ->
            modalityDir << modalityD
        }
        for (int i = 0; i < modalityDir.size(); i++) {
            File[] modalityFiles = modalityDir[i].listFiles();
            modalityFileName << modalityFiles
        }
        for (int j = 0; j < modalityFileName.size(); j++) {
            for (int k = 0; k < modalityFileName[j].size(); k++) {
                finalModalityName << modalityFileName[j][k]
            }
        }
        vars.putObject("All_Modality",finalModalityName);
    }
}
优化后的代码
import groovy.io.FileType

def dir = new File(vars.get("dirName"))
def selectionPattern = ["All", "Single"]
def rnd = new Random()
def userSelectionForModalityFolder = selectionPattern[rnd.nextInt(selectionPattern.size())]

def finalModalityFiles = []

// 1. 筛选并随机选择大小分类目录
def sizeDirs = dir.listFiles().findAll { it.isDirectory() }
if (!sizeDirs) {
    vars.putObject("All_Modality", finalModalityFiles)
    return
}
def randomSizeDir = sizeDirs[rnd.nextInt(sizeDirs.size())]

// 2. 筛选出CX/MX/VX类型目录
def modalityDirs = randomSizeDir.listFiles().findAll { 
    it.isDirectory() && (it.name in ["CX", "MX", "VX"]) 
}
if (!modalityDirs) {
    vars.putObject("All_Modality", finalModalityFiles)
    return
}

// 3. 根据选择规则确定要遍历的目标目录
def targetModalityDirs = userSelectionForModalityFolder == "All" 
    ? modalityDirs 
    : [modalityDirs[rnd.nextInt(modalityDirs.size())]]

// 4. 直接遍历目标目录下的系列子目录,收集所有图片文件
targetModalityDirs.each { modalityDir ->
    modalityDir.eachDir { seriesDir ->
        seriesDir.eachFile(FileType.FILES) { imgFile ->
            finalModalityFiles << imgFile
        }
    }
}

vars.putObject("All_Modality", finalModalityFiles)
优化说明
  1. 消除冗余中间集合:去掉原代码中list、listNew等7个不必要的中间列表,直接通过链式筛选与迭代收集最终文件,避免多次集合复制、扩容的内存开销。
  2. 精准目录过滤:使用findAll直接筛选出符合要求的大小目录与CX/MX/VX目录,跳过无关目录的遍历,减少IO操作次数。
  3. 提前边界检查:增加目录为空的判断逻辑,避免后续无意义的遍历操作,快速返回空结果。
  4. 直接收集文件:使用eachFile(FileType.FILES)直接遍历系列目录下的文件,无需先收集目录再遍历文件,减少一层嵌套与IO调用。
  5. 复用实例与简化逻辑:仅创建一个Random实例,合并All/Single分支的公共逻辑,同时修复原代码中ranSelect未定义就使用的潜在bug。

内容的提问来源于stack exchange,提问作者Jyoti Prakash Mallick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 06:27:37