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

.NET Core 6中如何加速PDF文件搜索循环?

性能优化方案

针对你当前的PDF搜索方法在处理1500个PDF文件+200个关键词时的性能瓶颈,从以下几个核心方向优化:

关键优化点

1. 提前预处理关键词,消除重复计算

当前代码在每个PDF的每个页面循环里重复执行keyword.ToLower().Trim(),完全可以在方法开头只做一次预处理:

// 方法入口处统一处理关键词,避免重复计算
var normalizedKeyword = keyword.ToLower().Trim();

2. 优先检查文件名/路径,跳过无意义的PDF解析

如果文件名或文件路径已经匹配关键词,直接加入结果,不需要再解析PDF内容,大幅节省磁盘IO和解析时间:

// 先判断文件名/路径是否匹配,匹配则直接加入结果并跳过后续逻辑
var fileLowerName = file.Name.ToLower();
var fileLowerFullPath = file.FullName.ToLower();
if (fileLowerName.Contains(normalizedKeyword) || fileLowerFullPath.Contains(normalizedKeyword))
{
    results.Add(new KeyValuePair<string, string>(keyword, file.FullName));
    continue;
}

3. 匹配到关键词后立即终止页面遍历

单个PDF只要有一个页面匹配关键词,就无需继续遍历剩余页面,直接跳出循环:

using (var document = new PdfDocument(file.FullName))
{
    foreach (var page in document.Pages)
    {
        var textLower = page.ExtractText().ToLower();
        if (textLower.Contains(normalizedKeyword))
        {
            results.Add(new KeyValuePair<string, string>(keyword, file.FullName));
            break; // 找到匹配后立刻停止页面遍历
        }
    }
}

4. 控制并发度,避免磁盘IO冲突

Parallel.ForEach默认会占用全部CPU核心,但PDF搜索属于IO密集型任务,过高并发会导致磁盘读写拥堵。手动设置合理的并发上限:

// 根据磁盘性能调整,机械硬盘建议设2-4,固态硬盘可设为CPU核心数
Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, file =>
{
    // 核心处理逻辑
});

5. 及时释放PDF资源,防止内存泄漏

使用using包裹PdfDocument,确保文件流和内存资源及时释放,避免内存占用过高影响后续性能:

using (var document = new PdfDocument(file.FullName))
{
    // 页面遍历与内容检查逻辑
}

6. 批量处理关键词(最核心的性能提升)

如果当前是循环调用SearchPdf处理200个关键词,会重复遍历1500个PDF200次,这是最大的性能浪费。改成一次遍历所有PDF,同时检查所有关键词:

public static ConcurrentBag<KeyValuePair<string, string>> SearchPdf(string path, List<string> keywords)
{
    var results = new ConcurrentBag<KeyValuePair<string, string>>();
    // 提前预处理所有关键词
    var normalizedKeywords = keywords.Select(k => k.ToLower().Trim()).ToList();

    var directory = new DirectoryInfo(path);
    var files = directory.GetFiles("*.pdf", SearchOption.AllDirectories);

    Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, file =>
    {
        var fileLowerName = file.Name.ToLower();
        var fileLowerFullPath = file.FullName.ToLower();
        var matchedKeywords = new List<string>();

        // 先检查文件名匹配的关键词
        foreach (var kw in normalizedKeywords)
        {
            if (fileLowerName.Contains(kw) || fileLowerFullPath.Contains(kw))
            {
                matchedKeywords.Add(kw);
            }
        }

        // 添加文件名匹配的结果
        foreach (var kw in matchedKeywords)
        {
            results.Add(new KeyValuePair<string, string>(kw, file.FullName));
        }

        // 过滤已匹配的关键词,只处理剩余的
        var remainingKeywords = normalizedKeywords.Except(matchedKeywords).ToList();
        if (!remainingKeywords.Any()) return;

        // 解析PDF内容检查剩余关键词
        using (var document = new PdfDocument(file.FullName))
        {
            foreach (var page in document.Pages)
            {
                var textLower = page.ExtractText().ToLower();
                var foundKeywords = remainingKeywords.Where(kw => textLower.Contains(kw)).ToList();
                
                foreach (var kw in foundKeywords)
                {
                    results.Add(new KeyValuePair<string, string>(kw, file.FullName));
                    remainingKeywords.Remove(kw);
                }

                if (!remainingKeywords.Any()) break; // 所有关键词都匹配,停止遍历页面
            }
        }
    });

    return results;
}

优化效果说明

  • 把200次PDF遍历压缩为1次,直接减少99%的磁盘IO开销
  • 提前过滤匹配的文件/关键词,避免大量无意义的PDF内容解析
  • 控制并发度避免磁盘拥堵,同时及时释放资源稳定内存占用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:45:26