[我只是想知道在性能方面哪个更好(我在FileStream中使用StreamWriter):
StreamWriter sw = new StreamWriter(fs);
for (int i = 0; i < 100; i++)
{
sw.Write(myList[i].ToString());
}
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。我还没有尝试过逐个字符,但逐行似乎足够好。