什么消耗更少的资源,并且更快地存储在StringBuilder中的File.AppendText或File.WriteAllText?

时间:2013-04-24 12:06:49

标签: c# performance streamwriter .net

我必须将数千条动态生成的行写入文本文件。 我有两个选择,它消耗的资源更少,而且比另一个更快?

:一种。使用StringBuilder和File.WriteAllText

StringBuilder sb = new StringBuilder();

foreach(Data dataItem in Datas)
{
    sb.AppendLine(
        String.Format(
            "{0}, {1}-{2}",
            dataItem.Property1,
            dataItem.Property2,
            dataItem.Property3));
}

File.WriteAllText("C:\\example.txt", sb.ToString(), new UTF8Encoding(false)); 

B中。使用File.AppendText

using(StreamWriter sw = File.AppendText("C:\\example.txt"))
{
    foreach (Data dataItem in Datas)
    {
        sw.WriteLine(
            String.Format(
                "{0}, {1}-{2}",
                dataItem.Property1,
                dataItem.Property2,
                dataItem.Property3));
    }
}

2 个答案:

答案 0 :(得分:15)

您的第一个版本将所有内容放入StringBuilder然后写入,将消耗最多的内存。如果文本非常大,则可能会耗尽内存。它有可能更快,但也可能更慢。

第二个选项将使用更少的内存(基本上只使用StreamWriter缓冲区),并且性能非常好。我会推荐这个选项。它表现良好 - 可能比第一种方法更好 - 而且没有相同的内存耗尽潜力。

通过增加输出缓冲区的大小,可以加快速度。而不是

File.AppendText("filename")

使用以下命令创建流:

const int BufferSize = 65536;  // 64 Kilobytes
StreamWriter sw = new StreamWriter("filename", true, Encoding.UTF8, BufferSize);

64K的缓冲区大小比默认的4K缓冲区大小提供了更好的性能。你可以做得更大,但我发现大于64K会带来最小的性能提升,而且在某些系统上实际上可以降低性能。

答案 1 :(得分:7)

您使用File.AppendAllLines()

至少还有一个其他选择
var data = from item in Datas
            select string.Format("{0}, {1}-{2}", item.Property1, item.Property2, item.Property3);

File.AppendAllLines("Filename", data, new UTF8Encoding(false));

理论上,这将比第一种方法使用更少的内存,因为一次只有一行将被缓冲在内存中。

它可能与你的第二种方法几乎完全相同。我只是向您展示第三种选择。这个的唯一优点是你可以用Linq序列喂它,这有时很有用。

I / O速度会使任何其他考虑因素相形见绌,因此您应该集中精力减少内存使用量,正如juharr所述(当然还要考虑过早优化的危险!)

这意味着使用你的第二种方法,或者我放在这里的方法。