最好是多次流式写或连接字符串和流.写一次

  • 本文关键字:一次 字符串 连接 c# .net file stream
  • 更新时间 :
  • 英文 :


我只是想知道,就性能而言,哪一个更好(我在FileStream中使用StreamWriter):

  1. 多次调用 Stream.Write():

StreamWriter sw = new StreamWriter(fs);
for (int i = 0; i < 100; i++)
{
    sw.Write(myList[i].ToString());
}

  1. 将所有字符串连接成一个字符串,然后调用 Steam.Write() 一次:

StreamWriter sw = new StreamWriter(fs);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++)
{
    sb.Append(myList[i].ToString());
}
sw.Write(sb.ToString());

谢谢!

这个问题没有单一的答案。您可以想象,逐字节或逐个字符写入通常会导致开销,因为每个数据块都通过抽象层。

但是,您也可以想象尽可能多地缓冲可能不是最佳的,即,如果通过网络流发送数据,则希望网络尽快开始传输数据。而且您的应用程序正忙于缓冲,因此您可能只是在移动延迟而不是修复任何内容。

在操作系统负责缓冲FileStream的情况下,在正常情况下,您可能不会注意到两种方法之间的任何差异。

只需按照最适合您的应用程序的方式写入数据,如果您发现这是应用程序的瓶颈,请在StreamWriter和底层Stream之间实现缓冲流层来解决此问题。

根据我的个人经验,在选择其中一个之前,您应该考虑其他一些事情:如果您逐行写入流线,则完整文本的每一行都有机会发生 I/O 异常(特别是在写入磁盘时);因此您要编写的行越多,您的代码就越容易出错。因此,如果两种方法之间没有显著差异,请考虑第二种方法,或者在编写完整文本的一半时出现异常时准备好恢复代码。

我用3种不同的方法测量了持续时间:

class Program
{
    private static readonly int NumLines = 100000;
    private static readonly int NumWords = 200;
    private static readonly string Word = "Oberbuergermeister";
    static void Main(string[] args)
    {
        var stopWatch = new Stopwatch();
        // approach 1: use string builder to cache all, then write
        stopWatch.Start();
        Approach1();
        stopWatch.Stop();
        Console.WriteLine(stopWatch.Elapsed.ToString());
        stopWatch.Reset();
        // approach 2: write stuff line by line
        stopWatch.Start();
        Approach2();
        stopWatch.Stop();
        Console.WriteLine(stopWatch.Elapsed.ToString());
        stopWatch.Reset();
        // approach 3: write stuff string by string
        stopWatch.Start();
        Approach3();
        stopWatch.Stop();
        Console.WriteLine(stopWatch.Elapsed.ToString());
    }
    private static void Approach1()
    {
        var writer = new System.IO.StreamWriter("C:\temp\1");
        var builder = new StringBuilder();
        for (int cnt1 = 0; cnt1 < NumLines; cnt1++)
        {
            for (int cnt2 = 0; cnt2 < NumWords; cnt2++)
            {
                builder.Append(Word);
                builder.Append(";");
            }
            builder.AppendLine();
        }
        writer.WriteLine(builder.ToString());
        writer.Close();
    }
    private static void Approach2()
    {
        var writer = new System.IO.StreamWriter("C:\temp\2");
        var builder = new StringBuilder();
        for (int cnt1 = 0; cnt1 < NumLines; cnt1++)
        {
            for (int cnt2 = 0; cnt2 < NumWords; cnt2++)
            {
                builder.Append(Word);
                builder.Append(";");
            }
            writer.WriteLine(builder.ToString());
            builder.Clear();
        }
        writer.Close();
    }
    private static void Approach3()
    {
        var writer = new System.IO.StreamWriter("C:\temp\3");
        for (int cnt1 = 0; cnt1 < NumLines; cnt1++)
        {
            for (int cnt2 = 0; cnt2 < NumWords; cnt2++)
            {
                writer.Write(Word);
                writer.Write(";");
            }
            writer.WriteLine();
        }
        writer.Close();
    }
}

下面是输出:

00:00:02.8457431
00:00:01.5492287
00:00:01.4843888
看起来最好尽可能

频繁地调用StreamWriter.Write()并将缓存完全留给 .NET。我还没有逐个尝试过字符,但无论如何,一行一行似乎已经足够好了。

相关内容

  • 没有找到相关文章

最新更新