ako*_*nsu 18 .net c# exception-handling
我的应用程序遍历目录树,并在每个目录中尝试打开具有特定名称的文件(使用File.OpenRead()).如果此调用抛出,FileNotFoundException则它知道该文件不存在.我宁愿在此File.Exists()之前打电话来检查文件是否存在?这会更有效吗?
Mar*_*ers 24
更新
我在循环中运行这两个方法并计时:
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();
Run Code Online (Sandbox Code Playgroud)
这些是未附加调试器并运行发布版本的结果:
Method Iterations per second throwException 10100 fileOpen 2200 fileExists 11300
抛出异常的成本远高于我的预期,并且在不存在的文件上调用FileOpen似乎比检查不存在的文件的存在慢得多.
在文件通常不存在的情况下,检查文件是否存在似乎更快.我想在相反的情况下 - 当文件通常存在时,你会发现捕获异常的速度更快.如果性能对您的应用程序至关重要,我建议您对实际数据的两个apporaches进行基准测试.
正如在其他答案中所提到的,请记住,即使你在打开它之前检查文件的存在,如果有人在你的存在检查之后但在你打开文件之前删除了文件,你应该小心竞争条件.您仍然需要处理异常.
Lie*_*yan 10
不,不.如果使用File.Exists,则会引入并发问题.如果你写了这段代码:
if file exists then
open file
Run Code Online (Sandbox Code Playgroud)
然后如果另一个程序在你检查File.Exists和实际打开文件之间删除了你的文件,那么程序仍然会抛出异常.
其次,即使文件存在,这并不意味着您实际上可以打开文件,您可能没有打开文件的权限,或者文件可能是只读文件系统,因此您无法在写入模式下打开,等等
文件I/O比异常要贵得多,不需要担心异常的性能.
编辑:在Linux下对Python中的异常与存在进行基准测试
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
Run Code Online (Sandbox Code Playgroud)
这种行为真的很特别吗?如果需要,您应该使用if语句进行测试,而不是使用异常.性能不是此解决方案的唯一问题,并且从您尝试执行的操作的声音来看,性能不应成为问题.因此,风格和良好的方法应该是这个解决方案的关注项目.
因此,总而言之,由于您希望某些测试失败,请使用File.Exists检查而不是在事后捕获异常.当然,您仍应捕获可能发生的其他异常.
运行目录搜索,找到它然后尝试打开它不是最有效的吗?
Dim Files() as string = System.IO.Directory.GetFiles("C:\", "SpecificName.txt", IO.SearchOption.AllDirectories)
Run Code Online (Sandbox Code Playgroud)
然后你会得到一个你知道存在的字符串数组.
哦,作为对原始问题的回答,我会说是的,try/catch会引入更多的处理器周期,我还假设IO peeks实际上花费的时间比处理器周期的开销要长.
首先运行存在,然后是打开的第二个,是2个IO功能,而不是试图打开它.实际上,我认为整体性能将是对处理器上的处理器时间与硬盘驱动器速度的判断.如果你有一个较慢的处理器,我会选择检查,如果你有一个快速处理器,我可能会选择try/catch.
| 归档时间: |
|
| 查看次数: |
1523 次 |
| 最近记录: |