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

PowerShell:为何文件对比耗时差异如此巨大?

PowerShell文件对比耗时差异大,如何准确统计实际耗时?

问题场景

我正在编写脚本对比两个文件夹的内容,当文件大小和时间戳相同时会进行二进制对比,并希望监控对比速度,但得到的结果差异极大。

测试代码片段

$sFolder_1 = "<folder 1 path, include trailing \>"
$sFolder_2 = "<folder 2 path, include trailing \>"

Get-ChildItem -Path $sFolder_1 -Recurse | ForEach-Object {
    $oItem_1   = $_
    $sItem_1   = $oItem_1.FullName
    $sItem_rel = $sItem_1.Substring($nLen_1)
    $sItem_2   = Join-Path $sFolder_2 $sItem_rel
    $sFile = if (Test-Path -Type Container $sItem_1) { "" } else { "F" }

    # 检查文件夹2中是否有对应项
    if (-not (Test-Path $sItem_2)) {
        $sResult = "Not in 2"
    } else {
        # 如果是文件则进行对比
        if ($sFile -eq "") {
            $sResult = "Found"
        } else {
            $nSize_1 = $oItem_1.Length
            $dTimeStart = Get-Date
            $nKb = ($nSize_1 / 1024)
            Write-Output "$dTimeStart : Checking file ($nKb kb)"
            if (Compare-Object (Get-Content $sItem_1) (Get-Content $sItem_2)) {
                $sResult = "Dif content"
            } else {
                $sResult = "Same"
            }
            $nTimeElapsed = ((Get-Date) - $dTimeStart).Ticks / 1e7
            $nSpeed = $nKb / $nTimeElapsed
            Write-Output "$nKb kb in $nTimeElapsed seconds, speed $nSpeed kb/sec."
        }
    }
    Write-Output $sResult
}

运行输出(四个GVI视频文件)

08/05/2023 08:58:41 : Checking file (75402.453125 kb)
75402.453125 kb in 37.389018 seconds, speed 2016.70054894194 kb/sec.
Same
08/05/2023 08:59:18 : Checking file (67386.28515625 kb)
67386.28515625 kb in 22.6866484 seconds, speed 2970.30588071573 kb/sec.
Same
08/05/2023 08:59:41 : Checking file (165559.28125 kb)
165559.28125 kb in 5.6360258 seconds, speed 29375.1815774158 kb/sec.
Same
08/05/2023 08:59:47 : Checking file (57776.244140625 kb)
57776.244140625 kb in 2.059942 seconds, speed 28047.5101437929 kb/sec.
Same

可以看到第三、第四个文件的对比速度比前两个快十倍,不符合常理,猜测是PowerShell的进程优化机制导致,请问如何准确统计每次对比的实际耗时?


原因分析与解决方案

耗时差异的核心原因

不是PowerShell的优化机制,而是系统文件缓存和低效的文件读取/对比方式共同导致:

  • 前两个文件首次读取时,数据从磁盘加载到内存缓存;后续文件直接从缓存读取,速度自然大幅提升。
  • Get-Content默认按文本行读取,对二进制视频文件完全不适用,会额外增加解析开销,首次读取时这个开销加上磁盘IO导致耗时很长。
  • Compare-Object需要把两个文件的全部内容加载到内存后再逐元素对比,对大文件来说内存占用高、效率低。

准确统计耗时的方法

用Measure-Command替代Get-Date计时,它是PowerShell专门用于测量命令执行时长的工具,精度更高,且能直接返回耗时的TimeSpan对象,无需手动计算。

优化后的对比脚本

下面是兼顾准确计时和高效二进制对比的代码:

$sFolder_1 = "<folder 1 path, include trailing \>"
$sFolder_2 = "<folder 2 path, include trailing \>"
$nLen_1 = $sFolder_1.Length

Get-ChildItem -Path $sFolder_1 -Recurse | ForEach-Object {
    $oItem_1 = $_
    $sItem_1 = $oItem_1.FullName
    $sItem_rel = $sItem_1.Substring($nLen_1)
    $sItem_2 = Join-Path $sFolder_2 $sItem_rel

    if (Test-Path -Type Container $sItem_1) {
        if (Test-Path $sItem_2) {
            Write-Output "Found"
        } else {
            Write-Output "Not in 2"
        }
        return
    }

    # 只处理文件
    if (-not (Test-Path -Type Leaf $sItem_2)) {
        Write-Output "Not in 2"
        return
    }

    $nSize_1 = $oItem_1.Length
    $nSize_2 = (Get-Item $sItem_2).Length
    if ($nSize_1 -ne $nSize_2) {
        Write-Output "Dif size"
        return
    }

    $nKb = $nSize_1 / 1024
    Write-Output "$(Get-Date) : Checking file ($nKb kb)"

    # 用Measure-Command计时,同时用高效的二进制对比
    $timeTaken = Measure-Command {
        $bytes1 = [System.IO.File]::ReadAllBytes($sItem_1)
        $bytes2 = [System.IO.File]::ReadAllBytes($sItem_2)
        $isSame = [System.Linq.Enumerable]::SequenceEqual($bytes1, $bytes2)
    }

    $sResult = if ($isSame) { "Same" } else { "Dif content" }
    $nTimeElapsed = $timeTaken.TotalSeconds
    $nSpeed = $nKb / $nTimeElapsed
    Write-Output "$nKb kb in $nTimeElapsed seconds, speed $nSpeed kb/sec."
    Write-Output $sResult
}

额外说明

如果需要排除系统缓存的影响(测试真实磁盘读取速度),可以在每次文件对比前执行以下命令清空缓存(需要管理员权限):

Clear-DiskCache -DevicePath "\\?\Volume{your-volume-guid}"

日常场景中缓存是正常的系统优化,无需刻意清空,除非是专门的磁盘性能测试。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:55:54