【问题标题】:Log to memory then write to file, memory stream vs file compared记录到内存然后写入文件,内存流和文件比较
【发布时间】:2012-06-13 13:06:48
【问题描述】:

这是参考我之前的问题Log to memory and then write to file,实际上是该问题的编辑部分,我在编辑部分询问如果我写入内存会比写入文件更快吗?我做了一个简单的测试,结果令人震惊!我想与社区分享。 这是代码

private void Button1Click(object sender, EventArgs e)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    File.AppendAllText(@"D:\File1.txt", string.Format("{0}Start! : {1}", Environment.NewLine, DateTime.Now.ToString(CultureInfo.InvariantCulture)));
    for (int i = 0; i < 6; i++)
    {
        for (int j = 0; j < 1000000; j++)
        {
             File.AppendAllText(@"D:\File1.txt", string.Format("{0}{1}:{2}", Environment.NewLine, i.ToString(CultureInfo.InvariantCulture), j.ToString(CultureInfo.InvariantCulture)));
         }
    }
    File.AppendAllText(@"D:\File1.txt", string.Format("{0}Done!{1}", Environment.NewLine, DateTime.Now.ToString(CultureInfo.InvariantCulture)));
    stopwatch.Stop();
    File.AppendAllText(@"D:\File1.txt",
                       string.Format("{0}{1}:{2}",Environment.NewLine,              stopwatch.Elapsed.ToString(), stopwatch.ElapsedMilliseconds.ToString(CultureInfo.InvariantCulture)));
    MessageBox.Show("Done!");
}

private void Button2Click(object sender, EventArgs e)
{
     var stopwatch = new Stopwatch();
     using (var mem = new MemoryStream())
     {
         using (var binaryWriter = new BinaryWriter(mem))
         {
             stopwatch.Start();
             {
                 binaryWriter.Write("start! : " + DateTime.Now.ToString(CultureInfo.InvariantCulture));
                 for (int i = 0; i < 6; i++)
                 {
                     for (int j = 0; j < 1000000; j++)
                     {
                         binaryWriter.Write(i.ToString(CultureInfo.InvariantCulture) + ":" + j.ToString(CultureInfo.InvariantCulture));
                     }
                 }
                 stopwatch.Stop();
                 binaryWriter.Write("Done! " + DateTime.Now.ToString(CultureInfo.InvariantCulture));
                 binaryWriter.Write(stopwatch.Elapsed.ToString() + ":" + stopwatch.ElapsedMilliseconds.ToString(CultureInfo.InvariantCulture));
                 binaryWriter.Flush();
                 var file = new FileStream(@"D:\File2.txt", FileMode.Create);
                 mem.WriteTo(file);
             }
         }
     }
     MessageBox.Show("Done!");
}

因为代码应该很容易理解

Elapsed time in File1.txt = 00:50:24.5654918  
Elapsed milliseconds in File1.txt = 3024565  
Elapsed time in File2.txt = 00:00:04.7430152  
Elapsed milliseconds in File2.txt = 4743

因此,您自己可以看到,大约存在 50 分钟的差异!如果您将所有内容直接记录到 IO 文件,而不使用内存,这可能是导致性能不佳的真正原因流或任何用于记录的自定义工具,OTOH 与 50 分钟的 File.AppendAllText 相比,使用 MemoryStream 只需要大约 4 又四分之一秒。 (我仍然很困惑为什么 windows 资源管理器中显示的时间与 stopwatch.ShowElapasedTime 最后显示的文件中的时间不对应,但尽管如此,即使我们看到 windows 资源管理器时间,它仍然是大约 45 分钟更快!)所以,这可能是一个非常有用的东西,我想分享它!

【问题讨论】:

  • 不是很令人震惊。只是做错了 IO 的结果。
  • @harold 这里有什么问题?
  • IO 以块的形式工作,流在它们之上以使其更易于管理。结果之一是编写一个小块所花费的时间与编写一个大块所花费的时间差不多。使用流,可以将所有短写入连接起来并写入一个大块。使用AppendAllText,它只需要写出你现在给它的任何东西,因为不能保证你会再次调用它。您已经有了流代码,也可以将其用于文件。

标签: c# performance file-io io stream


【解决方案1】:

这是因为 File.AppendAllText 打开文件、写入、刷新缓冲区并关闭它。如果您保持日志文件打开并使用流写入它(而不是 MemoryStream),您将获得与您在 MemoryStream 中看到的非常接近的结果 - 它甚至可能无法区分。

试试看。

【讨论】:

  • 实际上,对于大量数据,直接写入磁盘会变得相当快,因为​​它不需要在内存中重新分配巨大的数组(这也容易导致内存不足的异常)。
  • 如果您在打开文件时指定更大的缓冲区(最高约 64K),直接写入文件几乎肯定会更快。或者,您可以使用附加到输出流的BufferedStream
猜你喜欢
  • 2012-06-07
  • 1970-01-01
  • 2016-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多