Reputation: 233
I was just wondering, in terms of performance, which one is better (I'm using a StreamWriter in a FileStream):
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());
Thanks!
Upvotes: 3
Views: 2941
Reputation: 3229
I measured the duration using 3 different approaches:
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();
}
}
Here's the output:
00:00:02.8457431
00:00:01.5492287
00:00:01.4843888
Looks like it's best to call StreamWriter.Write()
as often as possible and completely leave the caching to .NET. I haven't tried char by char, but line by line seems to be good enough anyway.
Upvotes: 1
Reputation: 2164
In my personal experience, there's something else you should take on consideration before chosing one or another: if you write to the stream line by line, every line of the complete text is a chance for an I/O exception (specially when writing to disk); thus the more lines you're going to write, the more error-prone your code is. So, if there's no significant difference between your two approaches, either consider the second one, or have your code ready to recover if an exception ocurrs when writing half of the complete text.
Upvotes: 1
Reputation: 26436
There is no single answer to this. You can imagine that writing byte by byte, or character by character, usually causes overhead because each chunk of data travels through the layers of abstraction.
However you can also imagine that buffering as much as possible may not be optimal, ie. if you send data over a network stream, you would like the network to start transmitting data as soon as possible. And your application is busy buffering, so perhaps you're just moving the delay around instead of fixing anything.
In the case of a FileStream
the operating system takes care of buffering, in normal circumstances you probably won't notice any difference between your two approaches.
Just write the data as is most fitting for your application, and if you find this is a bottleneck to your application, implement a buffered stream layer between the StreamWriter
and the underlying Stream
to counter the problem.
Upvotes: 3