检查File.Exists()是否提高了写入速度

Dav*_*ave 8 c#

我的应用程序将一些文件写入光盘,但我意识到我在此过程中编写了现有文件.所以,我需要先检查文件是否存在,然后执行一些逻辑.

可能会有很多文件,因此,我想要估计影响会有多大(在时间方面).所以,我创建了一个控制台应用程序来测试它.

我的代码

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,正如您所看到的,它执行了2个操作.我正在将文件写入磁盘,另一种是检查文件是否已经存在,如果不存在,则写入光盘.

我的控制台窗口的屏幕截图(结果):

在此输入图像描述

正如您所看到的,奇怪的是,首先检查文件是否存在然后写入它比直接写入光盘几乎总是更快.这让我很困惑.当然这没有意义.为什么这个额外的头部提高了速度(考虑到File.Exists()我的代码中总会返回false,因此不会跳过Write)?我假设我的代码有问题,但我已经看了一段时间,我无法理解它.

编辑

根据评论,我稍微改变了顺序,所以我现在先执行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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Pet*_*ter 1

您的测试没有预热,并且您将 Exists 放在了计时之外。我想当您使用相同的文件时,它可以缓存在操作系统或硬件级别的某个位置。为了使这个测试更好:

  • 添加热身
  • 每次运行使用随机/唯一的文件名
  • 使用 1000、10000 和 100000 个文件进行测试
  • 确保您的 gc 在每次测试开始时处于相同的状态