将5000万条记录保存为CSV文件,每个文件保存20万条记录

本文关键字:文件 保存 记录 20万 5000万 CSV | 更新日期: 2023-09-27 18:17:22

我有一个生成数字并将其存储到List<int>的函数。
现在我必须尽快将这些结果存储到文件中。

下面是我的代码:
private void Save_Click(object sender, EventArgs e)
{
    //this is just for tests
    List<int> myResults = Enumerable.Range(1, 50000000).ToList();
    const string dir = @"D:'TESTS";
    int fileCount = 1;
    var file = Path.Combine(dir, string.Format("{0}.csv", fileCount));
    var sw = new StreamWriter(file, false);
    int i = 0;
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    foreach (int res in myResults.Shuffle())
    {
        sw.WriteLine(res);
        i++;
        if (i%200000 != 0) continue;
        fileCount++;
        sw.Close();
        file = Path.Combine(dir, string.Format("{0}.csv", fileCount));
        sw = new StreamWriter(file, false);
    }
    sw.Close();
    stopwatch.Stop();
    label3.Text = string.Format("Save time(s): {0:0.##}", stopwatch.Elapsed.TotalSeconds);
}

Shuffle是这个答案的扩展方法。

public static class Extensions
{
    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng = null)
    {
        if (rng == null)
            rng = new Random();
        T[] elements = source.ToArray();
        for (int i = elements.Length - 1; i > 0; i--)
        {
            int swapIndex = rng.Next(i + 1);
            yield return elements[swapIndex];
            elements[swapIndex] = elements[i];
        }
        yield return elements[0];
    }
}

我的问题是,保存大约需要5-7分钟在我的电脑上,当我增加结果的数量到1亿我得到OutOfMemoryException

我怎样才能加快速度并消除错误?

将5000万条记录保存为CSV文件,每个文件保存20万条记录

代码中最有问题的行是:

List<int> myResults = Enumerable.Range(1, 50000000).ToList();

:

foreach (int res in myResults.Shuffle())

尽量避免在堆上创建100亿个对象。相反,可以连续生成数据并立即将其写入磁盘,而不必将其保存在内存中。否则,内存管理和垃圾收集将成为瓶颈。

并将洗牌移到计时代码之外。我敢肯定相当多的时间都被拖拖拉拉的人占用了。

所以目前你衡量的是。net垃圾收集和排序算法的效率,而不是你真正想要衡量的,即写CSV文件需要多长时间。

我在我的笔记本上运行这段代码,不使用shuffle方法,耗时22秒。所以我想大部分时间都是用那个方法。

我建议你也不要在使用数据之前创建数据,因为这会消耗大量内存。创建一个枚举方法并逐行返回数据。

你还做了很多非常小的IO操作。更少的大的写操作,所以尝试批量写到磁盘。使用StringBuilder或类似的工具创建更大的数据块进行写入。您还可以查看BufferedWriter类。