我的应用程序将一些文件写入磁盘,但我意识到我在此过程中过度写入了现有文件。所以,我需要先检查文件是否存在,然后执行一些逻辑。
可能有很多文件,因此,我想衡量影响会产生多少开销(就时间而言)。所以,我创建了一个控制台应用程序来测试它。
我的代码
using System;
using System.Collections.Generic;
using System.IO;
namespace TimeForFileRead
{
class Program
{
static string myPath = "C:\\Users\\DRook\\Desktop\\temp\\";
static string myPathFile = myPath + "file";
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
DoSomeWork();
Console.WriteLine(" = = = = = =============== = = = = =");
}
Console.ReadKey();
}
static void DoSomeWork()
{
if (!Directory.Exists(myPath))
Directory.CreateDirectory(myPath);
System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
for (int i = 0; i < 1000; i++)
{
using (StreamWriter sw = new StreamWriter(myPathFile + i.ToString() + ".txt"))
{
sw.Write(i.ToString());
}
i++;
}
stopWatch.Stop();
Console.WriteLine("Write only: " + stopWatch.Elapsed);
Directory.Delete(myPath, true);
System.Threading.Thread.Sleep(500);
Directory.CreateDirectory(myPath);
System.Threading.Thread.Sleep(500);
stopWatch.Reset();
stopWatch.Start();
for (int i = 0; i < 1000; i++)
{
if (!File.Exists(myPathFile + i.ToString() + ".txt"))
{
using (StreamWriter sw = new StreamWriter(myPathFile + i.ToString() + ".txt"))
{
sw.Write(i.ToString());
}
}
i++;
}
stopWatch.Stop();
Console.WriteLine("Write and File check: " + stopWatch.Elapsed);
}
}
}
因此,如您所见,它执行 2 个操作。我正在将文件写入磁盘,另一个是检查文件是否已经存在,如果不存在,则写入磁盘。
我的控制台窗口的屏幕截图(结果):
如您所见,奇怪的是,首先检查文件是否存在然后将其写入几乎总是比直接写入磁盘要快。这让我很困惑。这当然没有任何意义。为什么这个额外的开销会提高速度(考虑到File.Exists()
在我的代码中总是会返回 false,因此不会跳过写入)?我假设我的代码有问题,但我已经看了一段时间,但我无法理解它。
编辑
根据评论,我稍微改变了顺序,所以我现在File.Exists()
先执行检查,然后执行只写。结果更加夸张(尽管我现在按照上面的代码迭代超过 10000 而不是 1000):
编辑 2
@MatthewWatson 注意到我的代码有问题,我已对其进行了更新以确保始终首先删除目录。同样的问题仍然存在,但发生率大大降低,但速度差异更大。
using System;
using System.Collections.Generic;
using System.IO;
namespace TimeForFileRead
{
class Program
{
static string myPath = "C:\\Users\\DRook\\Desktop\\temp\\";
static string myPathFile = myPath + "file";
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
DoSomeWork();
Console.WriteLine(" = = = = = =============== = = = = =");
}
Console.ReadKey();
}
static void DoSomeWork()
{
if (Directory.Exists(myPath))
Directory.Delete(myPath, true);
Directory.CreateDirectory(myPath);
System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
for (int i = 0; i < 10000; i++)
{
using (StreamWriter sw = new StreamWriter(myPathFile + i.ToString() + ".txt"))
{
sw.Write(i.ToString());
}
i++;
}
stopWatch.Stop();
Console.WriteLine("Write took : " + stopWatch.Elapsed);
Directory.Delete(myPath, true);
System.Threading.Thread.Sleep(500);
Directory.CreateDirectory(myPath);
System.Threading.Thread.Sleep(500);
stopWatch.Reset();
stopWatch.Start();
for (int i = 0; i < 10000; i++)
{
if (!File.Exists(myPathFile + i.ToString() + ".txt"))
{
using (StreamWriter sw = new StreamWriter(myPathFile + i.ToString() + ".txt"))
{
sw.Write(i.ToString());
}
}
i++;
}
stopWatch.Stop();
Console.WriteLine("Write and check took: " + stopWatch.Elapsed);
}
}
}