我正在运行一个程序来基准测试和迭代文件夹中大量文件的所有文件的速度.该过程中最慢的部分是创建100万加文件.我现在使用一个非常简单的方法创建文件:
Console.Write("Creating {0:N0} file(s) of size {1:N0} bytes... ",options.FileCount,options.FileSize); var createTimer = Stopwatch.StartNew(); var fileNames = new List<string>(); for (long i = 0; i < options.FileCount; i++) { var filename = Path.Combine(options.Directory.FullName,CreateFilename(i,options.FileCount)); using (var file = new FileStream(filename,FileMode.CreateNew,FileAccess.Write,FileShare.None,4096,FileOptions.WriteThrough)) { // I have an option to write some data to files,but it's not being used. // That's why there's a using here. } fileNames.Add(filename); } createTimer.Stop(); Console.WriteLine("Done."); // Other code appears here..... Console.WriteLine("Time to CreateFiles: {0:N3}sec ({1:N2} files/sec,1 in {2:N4}ms)",createTimer.Elapsed.TotalSeconds,(double)total / createTimer.Elapsed.TotalSeconds,createTimer.Elapsed.TotalMilliseconds / (double)options.FileCount);
输出:
Creating 1,000,000 file(s) of size 0 bytes... Done. Time to CreateFiles: 9,182.283sec (1,089.05 files/sec,1 in 9.1823ms)
如果有什么明显比这更好?我正在测试几个数量级以上的大于100万,创建文件需要一天的时间!
我没有尝试任何并行性,尝试优化任何文件系统选项或更改文件创建的顺序.
为了完整,这里是CreateFilename()的内容:
public static string CreateFilename(long i,long totalFiles) { if (totalFiles < 0) throw new ArgumentOutOfRangeException("totalFiles",totalFiles,"totalFiles must be positive"); // This tries to keep filenames to the 8.3 format as much as possible. if (totalFiles < 99999999) // No extension. return String.Format("{0:00000000}",i); else if (totalFiles >= 100000000 && totalFiles < 9999999999) { // Extend numbers into extension. long rem = 0; long div = Math.DivRem(i,1000,out rem); return String.Format("{0:00000000}",div) + "." + String.Format("{0:000}",rem); } else // Doesn't fit in 8.3,so just tostring the long. return i.ToString(); }
UPDATE
根据StriplingWarrior的建议使用Parallel.For()进行平行化.结果:大约30个线程颠簸我的磁盘和一个网速度下降!
var fileNames = new ConcurrentBag<string>(); var opts = new ParallelOptions(); opts.MaxDegreeOfParallelism = 1; // 1 thread turns out to be fastest. Parallel.For(0L,opts,() => new { Files = new List<string>() },(i,parState,state) => { var filename = Path.Combine(options.Directory.FullName,options.FileCount)); using (var file = new FileStream(filename,FileOptions.WriteThrough)) { } fileNames.Add(filename); return state; },state => { foreach (var f in state.Files) { fileNames.Add(f); } }); createTimer.Stop(); Console.WriteLine("Done.");
发现将FileStream中的FileOptions改成了〜50%.似乎我正在关闭任何写缓存.
new FileStream(filename,FileOptions.None)
结果:
Creating 10,000 file(s) of size 0 bytes... Done. Time to CreateFiles: 12.390sec (8,071.05 files/sec,1 in 1.2390ms)
其他想法仍然欢迎.