Powershell 问题 - 寻找最快的方法来遍历 500k 个对象以在另一个 500k 对象数组中寻找匹配项

Posted

技术标签:

【中文标题】Powershell 问题 - 寻找最快的方法来遍历 500k 个对象以在另一个 500k 对象数组中寻找匹配项【英文标题】:Powershell question - Looking for fastest method to loop through 500k objects looking for a match in another 500k object array 【发布时间】:2020-05-10 09:28:33 【问题描述】:

我有两个使用 import-csv cmdlet 导入的大型 .csv 文件。我做了很多搜索和尝试,终于发帖寻求帮助以使这更容易。

我需要遍历第一个数组,该数组的行数从 80k 到 500k 不等。这些数组中的每个对象都有多个属性,然后我需要在第二个相同大小的数组中找到对应的条目,匹配一个属性。

我将它们作为 [systems.collection.arrayList] 导入,并且我也尝试将它们放置为哈希表。我什至尝试过使用其他几篇文章中提到的 LINQ。

任何人都可以提供建议或见解如何使其运行得更快吗?感觉就像我在一个干草堆中寻找不同堆栈中的干草。

$ImportTime1 = Measure-Command 
    [System.Collections.ArrayList]$fileList1 = Import-csv file1.csv
    [System.Collections.ArrayList]$fileSorted1 = ($fileList1 | Sort-Object -property 'Property1' -Unique -Descending)
    Remove-Variable fileList1


$ImportTime2 = Measure-Command 
    [System.Collections.ArrayList]$fileList2 = Import-csv file2.csv
    [System.Collections.ArrayList]$fileSorted2 = ($fileList2 | Sort-Object -property 'Property1' -Unique -Descending)
    Remove-Variable fileList2


$fileSorted1.foreach(
     $varible1 = $_
     $target = $fileSorted2.where($_ -eq $variable1)
     ###do some other stuff
)

【问题讨论】:

这能回答你的问题吗? Which operator provides quicker output -match -contains or Where-Object for large CSV files 和 Fastest Way to get a uniquely index item from the property of an array 以及In Powershell, what's the best way to join two tables into one? 中提到的链接。如果您正在寻找现成的 LINQ 解决方案,请尝试:Join-Object from ili。 通常,性能结果可能取决于您的输入 - 甚至取决于您的(预期)输出对象(参见:Timing a command's execution in PowerShell),这意味着除了您尝试的更具体示例之外,最好添加一些示例输入数据和预期输出(另请参阅:How to Ask)。 【参考方案1】:

这可能有用:https://powershell.org/forums/topic/comparing-two-multi-dimensional-arrays/

评论 #27359 中的更新解决方案 + 在评论 #27380 中添加 Max Kozlov 建议的更改。

Function RJ-CombinedCompare() 
    [CmdletBinding()]
    PARAM(
        [Parameter(Mandatory=$True)]$List1,
        [Parameter(Mandatory=$True)]$L1Match,
        [Parameter(Mandatory=$True)]$List2,
        [Parameter(Mandatory=$True)]$L2Match
    )
    $hash = @
    foreach ($data in $List1) $hash[$data.$L1Match] += ,[pscustomobject]@Owner=1;Value=$($data)
    foreach ($data in $List2) $hash[$data.$L2Match] += ,[pscustomobject]@Owner=2;Value=$($data)
    foreach ($kv in $hash.GetEnumerator()) 
        $m1, $m2 = $kv.Value.where($_.Owner -eq 1, 'Split')
        [PSCustomObject]@
            MatchValue = $kv.Key
            L1Matches = $m1.Count
            L2Matches = $m2.Count
            L1MatchObject = $L1Match
            L2MatchObject = $L2Match
            List1 = $m1.Value
            List2 = $m2.Value
        
    


$fileList1 = Import-csv file1.csv
$fileList2 = Import-csv file2.csv

$newList = RJ-CombinedCompare -List1 $fileList1 -L1Match $(yourcolumnhere) -List2 $fileList2 -L2Match $(yourothercolumnhere)

foreach ($item in $newList) 
    # your logic here

将列表传递到这个哈希表应该很快,并且迭代也很快。

【讨论】:

以上是关于Powershell 问题 - 寻找最快的方法来遍历 500k 个对象以在另一个 500k 对象数组中寻找匹配项的主要内容,如果未能解决你的问题,请参考以下文章

寻找最快的视频编码器,将网络摄像头流式传输到 ipad

订购巨大载体的最快方法?

2D滚动窗口分位数的最快方法?

在python中合并两个列表的最快方法是啥?

从最后可用数据创建 DataFrame 的最快方法

搜索硬盘中所有文件的最快方法是啥?