Not all bytes weight exactly 8 bits
Or, pay attention to how you write to the disk. Here is a simple example:
static void Main(string[] args)
{
var count = 10000000;
Stopwatch stopwatch = Stopwatch.StartNew();
using (var stream = CreateWriter())
using (var bw = new BinaryWriter(stream))
{
for (var i = 0; i < count; i++)
{
bw.Write(i);
}
bw.Flush();
}
stopwatch.Stop();
Console.WriteLine("Binary Writer: " + stopwatch.ElapsedMilliseconds);
stopwatch = Stopwatch.StartNew();
using (var stream = CreateWriter())
{
for (var i = 0; i < count; i++)
{
var bytes = BitConverter.GetBytes(i);
stream.Write(bytes, 0, 4);
}
stream.Flush();
}
stopwatch.Stop();
Console.WriteLine("BitConverter: " + stopwatch.ElapsedMilliseconds);
stopwatch = Stopwatch.StartNew();
using (var stream = CreateWriter())
using (var ms = new MemoryStream())
{
for (var i = 0; i < count; i++)
{
var bytes = BitConverter.GetBytes(i);
ms.Write(bytes, 0, 4);
}
var array = ms.ToArray();
stream.Write(array, 0, array.Length);
stream.Flush();
}
stopwatch.Stop();
Console.WriteLine("Memory stream: " + stopwatch.ElapsedMilliseconds);
stopwatch = Stopwatch.StartNew();
using (var stream = CreateWriter())
{
byte[] buffer = new byte[sizeof(int) * count];
int index = 0;
for (var i = 0; i < count; i++)
{
buffer[index++] = (byte)i;
buffer[index++] = (byte)(i >> 8);
buffer[index++] = (byte)(i >> 16);
buffer[index++] = (byte)(i >> 24);
}
stream.Write(buffer, 0, buffer.Length);
stream.Flush();
}
stopwatch.Stop();
Console.WriteLine("Single buffer: " + stopwatch.ElapsedMilliseconds);
}
private static FileStream CreateWriter()
{
return new FileStream(Path.GetTempFileName(), FileMode.Create,
FileAccess.Write, FileShare.Read, 0x10000,
FileOptions.SequentialScan | FileOptions.WriteThrough);
}
And the results:
Binary Writer: 1877
BitConverter: 1985
Memory stream: 1702
Single buffer: 1022