C# - 排序File.ReadLines IEnumerable没有内存开销?

时间:2018-03-31 13:01:07

标签: c#

这可能吗?

我有以下代码来减少内存使用总量:

    Private Sub buttonSD_Click(sender As Object, e As RoutedEventArgs) Handles buttonSD.Click
        AngkaPertama = textBox1.Text
        AngkaKedua = textBox2.Text

        If Kalkulasi = "+" Then
            Hasil = AngkaPertama + AngkaKedua
        ElseIf Kalkulasi = "-" Then
            Hasil = AngkaPertama - AngkaKedua
        ElseIf Kalkulasi = "*" Then
            Hasil = AngkaPertama * AngkaKedua
        ElseIf Kalkulasi = "/" Then
            Hasil = AngkaPertama / AngkaKedua
        End If

        textBoxHasil.Text = Hasil
    End Sub

(file [0]是输入文件路径)。

这减少了ForEach e.t.c的使用,减少了CPU使用量以及内存使用量(几乎没有)。 它也比使用Foreach更快。 然而,问题是.OrderBy(s => s)导致它将整个内容加载到内存中。它没有像正常加载到内存中那么糟糕,但它仍然会上升相当多的内存。 (我使用80mb文件)。

在没有使用太多内存的情况下保存到文件时,有没有办法通过A-> Z来订购IEnumerable / Order?

我知道这听起来含糊不清,不确定我在寻找什么,因为我不了解自己。

在270万行文件上使用.OrderBy(s => s)运行:
https://i.imgur.com/rUyDeFJ.gifv

在270万行文件上运行WITHOUT .OrderBy(s => s):
https://i.imgur.com/Ejbnuty.gifv
(你可以看到它完成)

1 个答案:

答案 0 :(得分:1)

.OrderBy必须将整个内容加载到内存中。它不可能以任何其他方式工作。

OrderBy收到一个IEnumerable。因此,它一次接收项目。但是,请考虑最后一行需要在第一行之前排序的情况。只有当最后一行和第一行同时存在于内存中时,才能实现这一点。考虑整个输入已按相反顺序排序的情况。希望这些示例说明为什么OrderBy必须将整个内容加载到内存中。

存在将数据集划分到磁盘上的各个分区,然后合并这些分区的算法。但是,它们超出了Linq OrderBy函数的范围。

内部OrderBy将所有内容读入缓冲区数组,然后对其执行快速排序。如果你有勇气,请参考参考资料来源: https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,2530 (它分散在整个文件中,但第2534-2542行最能说明这一点)