performance - 如何检查/强制执行下一个 cmdlet 以获取管道对象
问题描述
我对如何在 Powershell 中对 3000 万条 csv 记录进行排序这个问题很感兴趣,并提出了一个构建临时文件的解决方案。现在我正在尝试提出另一种方法,它首先构建一个排序的索引列表([int[]]
),然后从源文件中选择大部分索引(例如1e6
)并将它们放到管道中:
Function Sort-BigCsv {
[CmdletBinding()] param(
[string]$FilePath,
[String]$Property,
[Int]$BulkSize = 1e6,
[System.Text.Encoding]$Encoding = [System.Text.Encoding]::Default
)
Begin {
if ($FilePath.StartsWith('.\')) { $FilePath = Join-Path (Get-Location) $FilePath }
$Index = 0
$Dictionary = [System.Collections.Generic.SortedDictionary[string, int]]::new()
Import-Csv $FilePath -Encoding $Encoding | Foreach-Object { $Dictionary[$_.$Property] = $Index++ }
$IndexList = [int[]]($Dictionary.Values)
$Dictionary = $Null # we only need the sorted index list
}
Process {
$Start = 0
While ($Start -lt $IndexList.Count) {
[System.GC]::Collect()
$End = $Start + $BulkSize - 1
if ($End -ge $IndexList.Count) { $End = $IndexList.Count - 1 }
Import-Csv $FilePath -Encoding $Encoding |
Select-Object -Index $IndexList[$Start..$End] | # Note that the -Index parameter reorders the list
Sort-Object $Property | # Consider smarter sort as this has already be done before
$Start = $End + 1
}
}
}
例子:
Sort-BigCsv .\Input.Csv Id -BulkSize 100 # | Export-Csv .\Output.Csv
我认为这背后的一般想法应该可行,但我第二次猜测 PowerShell 在将对象传递给下一个 cmdlet(/display) 方面实际上在做什么,并且出现的问题如下:
- 每一个项目(包括在一个块周期内创建的多个项目
Process
)总是会立即被下一个 cmdlet 拾取和处理吗? - 如果我将块中的所有内容都放入块中,此功能会有什么不同吗?
Process
End
- 如果下一个进程块比当前块慢怎么办?
- 它会阻止当前的吗?
- 或者这些项目会被缓冲吗?
- 如果它们被缓冲,我可以强制它们被下一个 cmdlet 使用,还是等到它们被消耗掉?
也许它只是按预期工作(很难从任务管理器中的内存大小中分辨出来),但我想确认这一点......是否有任何检查和/或控制是否传递项目(或写输出之后总是这样吗?意思是,如果最后一个 cmdlet 停止,第一个 cmdlet 也需要停止...)
解决方案
推荐阅读
- visual-studio-code - Visual Studio Code Terminal 找不到 `lesspipe` 命令
- python - 如何修复导入错误:使用 VScode 在 python 中没有名为...的模块
- excel - 为什么逗号分隔或命名范围 SEARCH() 函数在 Excel 中不起作用
- linux - 如何在不同的操作系统上处理 fileinfo.sys()
- python - 从 Tensorflow 迁移到 PyTorch 时模型定义的注意事项
- haskell - 如何产生无限二叉树?
- r - 替换特殊字符不适用于 gsub
- vue.js - 如何推送具有不同参数的路线?
- python - 如何在 Python 中跟踪用户的猜测?尝试 = 尝试 + 1 不起作用
- ruby-on-rails - postgreSQL 日期记录仅在 Rails 中持续到某个时间点