Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异常会降低性能吗?_C#_.net_Exception Handling - Fatal编程技术网

C# 异常会降低性能吗?

C# 异常会降低性能吗?,c#,.net,exception-handling,C#,.net,Exception Handling,我的应用程序遍历目录树,并在每个目录中尝试打开具有特定名称的文件(使用file.OpenRead())。如果此调用抛出FileNotFoundException,则它知道该文件不存在。我是否希望在此之前调用File.Exists()来检查文件是否存在?这会更有效吗?更新 我在一个循环中运行这两个方法,并对每个方法进行计时: void throwException() { try { throw new NotImplementedException();

我的应用程序遍历目录树,并在每个目录中尝试打开具有特定名称的文件(使用
file.OpenRead()
)。如果此调用抛出
FileNotFoundException
,则它知道该文件不存在。我是否希望在此之前调用
File.Exists()
来检查文件是否存在?这会更有效吗?

更新

我在一个循环中运行这两个方法,并对每个方法进行计时:

void throwException()
{
    try
    {
        throw new NotImplementedException();
    }
    catch
    {
    }
}

void fileOpen()
{
    string filename = string.Format("does_not_exist_{0}.txt", random.Next());
    try
    {
        File.Open(filename, FileMode.Open);
    }
    catch
    {
    }
}

void fileExists()
{
    string filename = string.Format("does_not_exist_{0}.txt", random.Next());
    File.Exists(filename);
}

Random random = new Random();
以下是未连接调试程序且未运行发布版本的结果:

方法每秒迭代次数 ThroweException 10100 fileOpen 2200 文件存在11300 抛出异常的成本比我预期的要高很多,对不存在的文件调用FileOpen似乎比检查不存在的文件的存在慢得多

在文件通常不存在的情况下,检查文件是否存在似乎更快。我可以想象,在相反的情况下——当文件通常存在时,您会发现捕获异常的速度更快。如果性能对应用程序至关重要,我建议您根据实际数据对这两种方法进行基准测试


正如在其他答案中提到的,请记住,即使在打开文件之前检查文件是否存在,如果有人在检查文件是否存在后但在打开文件之前删除了文件,也应注意竞争条件。您仍然需要处理异常。

一般来说,异常“提高”了系统的整体“性能”


无论如何,在您的示例中,最好使用File.Exists…

这种行为真的是例外吗?如果是预期的,您应该使用If语句进行测试,而不使用任何异常。性能不是此解决方案的唯一问题,从您尝试执行的声音来看,性能不应该是一个问题。因此,风格和良好的方法应该是该解决方案关注的事项


因此,总而言之,由于您预期某些测试会失败,请使用文件.Exists进行检查,而不是在事后捕获异常。当然,您仍然应该捕获可能发生的其他异常。

不,不要。如果使用File.Exists,则会引入并发问题。如果您编写了此代码:

if file exists then 
    open file
然后,如果在您选中file.Exists和实际打开文件之前,另一个程序删除了您的文件,则该程序仍将抛出异常

第二,即使文件存在,也不意味着您可以实际打开该文件,您可能没有打开该文件的权限,或者该文件可能是只读文件系统,因此无法以写模式打开,等等

文件I/O比异常昂贵得多,不需要担心异常的性能

编辑: Linux下Python中存在基准测试异常vs

import timeit
setup = 'import random, os'

s = '''
try:
    open('does not exist_%s.txt' % random.randint(0, 10000)).read()
except Exception:
    pass
'''
byException = timeit.Timer(stmt=s, setup=setup).timeit(1000000)

s = '''
fn = 'does not exists_%s.txt' % random.randint(0, 10000)
if os.path.exists(fn):
    open(fn).read()
'''
byExists = timeit.Timer(stmt=s, setup=setup).timeit(1000000)

print 'byException: ', byException   # byException:  23.2779269218
print 'byExists: ', byExists  # byExists:  22.4937438965

我不知道效率如何,但我更喜欢文件存在检查。问题是可能发生的所有其他事情:错误的文件句柄,等等。如果您的程序逻辑知道有时文件不存在,并且您希望现有文件与不存在的文件具有不同的行为,请使用file.Exists。如果其不存在与其他文件相关的异常相同,则只需使用异常处理

  • --关于如何更好地使用异常的更多信息

使用File.首先存在的问题是它也会打开文件。因此,您最终会打开文件两次。我没有对它进行测量,但是我想额外打开文件比偶尔的异常要昂贵


如果File.Exists检查提高了性能,则取决于文件存在的可能性。如果它可能存在,则不要使用File.exists,如果它通常不存在,则附加检查将提高性能。

是的,您应该使用File.exists。异常应用于不控制程序正常流的异常情况。在您的情况下,不存在文件不会发生异常情况。因此,您不应该依赖异常

更新:

所以每个人都可以自己尝试,我将发布我的测试代码。对于不存在的文件,依赖File.Open为您引发异常比使用File.Exists检查要糟糕50倍左右

class Program
{
   static void Main(string[] args)
   {
      TimeSpan ts1 = TimeIt(OpenExistingFileWithCheck);

      TimeSpan ts2 = TimeIt(OpenExistingFileWithoutCheck);

      TimeSpan ts3 = TimeIt(OpenNonExistingFileWithCheck);

      TimeSpan ts4 = TimeIt(OpenNonExistingFileWithoutCheck);
   }

   private static TimeSpan TimeIt(Action action)
   {
      int loopSize = 10000;

      DateTime startTime = DateTime.Now;
      for (int i = 0; i < loopSize; i++)
      {
         action();
      }

      return DateTime.Now.Subtract(startTime);
   }

   private static void OpenExistingFileWithCheck()
   {
      string file = @"C:\temp\existingfile.txt";
      if (File.Exists(file))
      {
         using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read))
         {
         }
      }
   }

   private static void OpenExistingFileWithoutCheck()
   {
      string file = @"C:\temp\existingfile.txt";
      using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read))
      {
      }
   }

   private static void OpenNonExistingFileWithCheck()
   {
      string file = @"C:\temp\nonexistantfile.txt";
      if (File.Exists(file))
      {
         using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read))
         {
         }
      }
   }

   private static void OpenNonExistingFileWithoutCheck()
   {
      try
      {
         string file = @"C:\temp\nonexistantfile.txt";
         using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read))
         {
         }
      }
      catch (Exception ex)
      {
      }
   }
}
类程序
{
静态void Main(字符串[]参数)
{
TimeSpan ts1=TimeIt(使用Check打开现有文件);
TimeSpan ts2=TimeIt(打开现有文件而不检查);
TimeSpan ts3=TimeIt(使用Check打开不存在的文件);
TimeSpan ts4=TimeIt(打开不存在的文件而不检查);
}
专用静态时间跨度TimeIt(操作)
{
int loopSize=10000;
DateTime startTime=DateTime.Now;
for(int i=0;iclass Program
{
   static void Main(string[] args)
   {
      TimeSpan ts1 = TimeIt(OpenExistingFileWithCheck);

      TimeSpan ts2 = TimeIt(OpenExistingFileWithoutCheck);

      TimeSpan ts3 = TimeIt(OpenNonExistingFileWithCheck);

      TimeSpan ts4 = TimeIt(OpenNonExistingFileWithoutCheck);
   }

   private static TimeSpan TimeIt(Action action)
   {
      int loopSize = 10000;

      DateTime startTime = DateTime.Now;
      for (int i = 0; i < loopSize; i++)
      {
         action();
      }

      return DateTime.Now.Subtract(startTime);
   }

   private static void OpenExistingFileWithCheck()
   {
      string file = @"C:\temp\existingfile.txt";
      if (File.Exists(file))
      {
         using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read))
         {
         }
      }
   }

   private static void OpenExistingFileWithoutCheck()
   {
      string file = @"C:\temp\existingfile.txt";
      using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read))
      {
      }
   }

   private static void OpenNonExistingFileWithCheck()
   {
      string file = @"C:\temp\nonexistantfile.txt";
      if (File.Exists(file))
      {
         using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read))
         {
         }
      }
   }

   private static void OpenNonExistingFileWithoutCheck()
   {
      try
      {
         string file = @"C:\temp\nonexistantfile.txt";
         using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read))
         {
         }
      }
      catch (Exception ex)
      {
      }
   }
}
Dim Files() as string = System.IO.Directory.GetFiles("C:\", "SpecificName.txt", IO.SearchOption.AllDirectories)