为什么要将多个小字节数组写入文件比写一个大数组要快?

Ale*_*ose 5 c# arrays io performance

我做了一个测试,看看从单字节数组写入磁盘上的1GB文件到从1024个数组写入另一个1GB文件所需的时间(每个1MB)之间是否存在差异.

测试编写许多数组
331.6902 ms
测试编写大数组
14756.7559 ms

对于此测试,"many arrays"实际上是一个byte[1024 * 1024]使用for循环写入1024次的单个数组."大数组"只是一个填充了随机值的1GB字节数组.

这是代码的样子:

Console.WriteLine("Test Writing many arrays");

byte[] data = new byte[1048576];

for (int i = 0; i < 1048576; i++)
    data[i] = (byte)(i % 255);

FileStream file = new FileStream("test.txt", FileMode.Create);

sw1.Restart();

for (int i = 0; i < 1024; i++ )
     file.Write(data, 0, 1048576);

file.Close();
sw1.Stop();
s1 = sw1.Elapsed;
Console.WriteLine(s1.TotalMilliseconds);

Console.WriteLine("Test Writing big array");


 byte[] data2 = new byte[1073741824];

 for (int i = 0; i < 1073741824; i++)
      data2[i] = (byte)(i % 255);

 FileStream file2 = new FileStream("test2.txt", FileMode.Create);

 sw1.Restart();

 file2.Write(data2, 0, 1073741824);

 file2.Close();
 sw1.Stop();

 s1 = sw1.Elapsed;
 Console.WriteLine(s1.TotalMilliseconds);
Run Code Online (Sandbox Code Playgroud)

file.Close()在定时部分中包含了内部,因为它调用了Flush()方法并将流写入磁盘.

生成的文件大小完全相同.

我认为可能C#可以看到我总是使用相同的数组,它可能会优化迭代/写入过程,但结果不会快2-3倍,速度快约45倍......为什么?

das*_*ght 5

我认为造成重大差异的主要原因是操作系统设法缓存几乎整个1GB写入,你在小块中做.

您需要更改基准设置的方式:代码应该写入相同的数据,第一次以1024块为单位,第二次以一块为单位.您还需要通过指定来关闭操作系统中数据的缓存FileOptions.WriteThrough,如下所示:

var sw1 = new Stopwatch();
Console.WriteLine("Test Writing many arrays");
var data = new byte[1073741824];
for (var i = 0; i < 1073741824; i++)
    data[i] = (byte)(i % 255);
var file = new FileStream("c:\\temp\\__test1.txt", FileMode.Create, FileSystemRights.WriteData, FileShare.None, 8, FileOptions.WriteThrough);
sw1.Restart();
for (int i = 0; i < 1024; i++)
    file.Write(data, i*1024, 1048576);
file.Close();
sw1.Stop();
var s1 = sw1.Elapsed;
Console.WriteLine(s1.TotalMilliseconds);
Console.WriteLine("Test Writing big array");
var file2 = new FileStream("c:\\temp\\__test2.txt", FileMode.Create, FileSystemRights.WriteData, FileShare.None, 8, FileOptions.WriteThrough);
sw1.Restart();
file2.Write(data, 0, 1073741824);
file2.Close();
sw1.Stop();
s1 = sw1.Elapsed;
Console.WriteLine(s1.TotalMilliseconds);
Run Code Online (Sandbox Code Playgroud)

运行此代码时,结果如下所示:

Test Writing many arrays
5234.5885
Test Writing big array
5032.3626
Run Code Online (Sandbox Code Playgroud)