我目前正在Windows Powershell中使用此命令从简单的1行CSV中删除重复项.
gc combine.csv | sort | get-unique > tags.cs
Run Code Online (Sandbox Code Playgroud)
每当我在一个150mb的CSV(2000万行猜测)上运行它时,任务管理器会显示Powershell占用所有可用内存(32GB)然后使用虚拟内存.我也让脚本运行了大约一个小时,但它没有完成.我发现这很奇怪,因为在excel中通常需要几秒钟才能从我的1M行CSVS中删除重复项.有关如何处理这个的任何建议?
你可以尝试:
Get-Content combine.csv -ReadCount 1000 |
foreach-object { $_ } |
Sort-Object -Unique |
Set-Content tags.cs
Run Code Online (Sandbox Code Playgroud)
(gc combine.csv -read 1kb | % { $_ } | sort -uniq | sc tags.cs)
但我认为你会遇到同样的问题.如果您想要更快的结果,并且它们不需要排序,则只需要重复免费:
$Lines = [System.Collections.Generic.HashSet[string]]::new()
$Lines.UnionWith([string[]][System.IO.File]::ReadAllLines('c:\path\to\combine.csv'))
[System.IO.File]::WriteAllLines('c:\path\to\tags.cs', $Lines)
Run Code Online (Sandbox Code Playgroud)
这是我在23秒内测试20M随机数文件和~1.5GB内存.如果确实需要进行排序,请使用5分钟内运行SortedSet而不是HashSet<2GB内存.虽然您的代码仍在运行,目前已通过15GB.
编辑:tiberriver256注释,[System.IO.File]::ReadLines而不是ReadAllLines可以在文件读完之前流式传输; 它返回一个枚举器而不是所有行的最终数组.在HashSet案例中,这会将运行时间从12.5秒降低到11.5秒 - 它变化太大而无法确定,但它似乎有所帮助.
Excel旨在处理有效的文件(显然?我实际上有点惊讶).
您的代码的主要问题是您正在对它进行排序.我知道你这样做是因为Get-Unique需要它,但是它的Sort-Object工作方式是它需要收集每个被发送到它的项目(在这种情况下,文件的每一行)以便实际进行排序.与文件不同,它不只是将其存储为平面内存,而是将其存储为N个字符串,其中N是文件中的行数,以及这些内存中字符串的所有开销.正如TessellatingHeckler指出的那样,它似乎与排序有关,而不是存储!
您可能希望确定给定的行在处理时是否唯一,因此您可以立即丢弃它.
为此,我会推荐套装.特别是一个HashSet,或者,如果你真的需要它排序,一个SortedSet.
您的代码的简单转换:
Get-Content combine.csv |
ForEach-Object -Begin {
$h = [System.Collections.Generic.HashSet[String]]::new()
} -Process {
if ($h.Add($_)) {
$_
}
} |
Set-Content tags.cs
Run Code Online (Sandbox Code Playgroud)
对我来说,在一个> 650 MB的文件中测试这个,大约有4条线路,其中只有26条是唯一的,只花了一分多钟,并没有明显影响RAM.
大约一半行独特的同一文件大约需要2分钟,并使用大约2 GB的RAM(SortedSet需要花费2.5分钟以上,大约2.4 GB).
相同的后一个文件,即使在~10秒内简化| sort | gu为| sort -Unique使用超过5 GB的RAM.
如果你开始使用StreamReader.ReadLine和for循环,以及其他一些事情,你可以挤出更多的性能,但我会留给你练习.
在大多数实现中,似乎在最好的情况下,使用的RAM量将高度依赖于有多少项是唯一的(更多唯一项意味着更多RAM).
| 归档时间: |
|
| 查看次数: |
833 次 |
| 最近记录: |