试试看。块块总是很贵?

可能重复:
当没有抛出exception时,try / catch块是否会损害性能?

嘿大家,关于try..catch块的快速问题。 我听说它们使用起来很昂贵,不应该用作程序流程的一部分。 但是,为了validation电子邮件地址,我使用以下代码。

try { MailAddress checkEmail = new MailAddress(testEmail); return true; } catch { return false; } 

由于事先validation,我没有很多例外被捕获,除非它试图绕过validation。 我的问题是,尝试…如果捕获到exception,Catch块只是昂贵的,或者无论是否抛出任何exception,它总是很昂贵?

谢谢

编辑 :感谢所有的回复。 我已经决定,因为检查(在C#中)不是很贵,我会坚持使用这种方法。 这主要是因为抛出的实际exception是罕见的,因为先前的validation步骤确保没有人意外地输入无效的电子邮件地址。

一般来说 ,在今天的实现中,输入try块并不昂贵(这并非总是如此)。 但是,抛出和处理exception通常是相对昂贵的操作。 因此,exception通常应用于exception事件,而不是正常的流量控制。

但是,性能只是需要考虑的一个因素,尤其是在现代世界中。 如果(例如)你正在做一次响应用户操作的事情,从性能角度来看,即使你可以进行主动检查,你是否使用exception并不重要,只要exception发生得足够快用户不是jolted.¹但是如果你在一个紧凑的循环中做一些事情会运行数十万次,或者你正在编写一个可能需要处理巨大负载的web应用程序,你可能我想避免在正常情况下使用例外。


¹十多年前,我负责增强.Net 1.1“无触摸部署”应用程序,其中第一次抛出exception需要三秒钟。 在一个用例中涉及打开文件时,这是一个足够的问题,用户要求的文件可能合理地不存在,我必须在尝试打开文件之前添加对文件存在的检查,这通常是糟糕的编程习惯(只是尝试打开文件并处理exception(如果失败),纯粹是因为等待该exception构建的用户体验非常糟糕。 但那可能不是我们现在生活的世界。

除非有例外,否则它们相当便宜。 因此,当您需要例外时,应该避免使用它们,如上例所示。

我认为用户输入不良的例外通常是不明智的。 内存不足或其他意外故障的例外情况很好。

只是为了扮演恶魔倡导者 – 我发现使用Exceptions进行流量控制非常有用:“取消”按钮。

如果你有一个函数在某个服务上运行可能需要10-120分钟,这是做了很多不同的事情,我发现if if(hasCanceled)在我的Log()函数中抛出新的JobCancelledException()记录每一步我正在工作只是friggan真棒。 它摆脱了当前的代码执行并停止运行作业 – 正是我所需要的。 我确信有一些更好的方法可以做到,也许某种程度上使用事件 – 但对于我的情况它很有效(特别是因为工作没有定期取消)。

除此之外 – 我100%同意Exceptions永远不应该用作流量控制工具..

@Kornel – 我的post有两个字……神圣的$ hit =)

这是一个简单的伪代码示例:

 Class Job { Public Run(param1,param2,etc...) { Try { Log("Doing Something") DoSomething() Log("Doing Another") DoAnother() Log("This keeps going, etc, inside of these function we make the same Log calls where it makes sense") Etc() } Catch(JobCancelledException) { status="Cancelled" } } Private Log(ByVal str As String) { MessateToUser(str) if(hasCancelled) throw new JobCancelledException } private SomeEvent_WhenUserPushesCancelButton() { hasCancelled=True } } 

try..catch块永远不应该用作程序流控制的工具。

如果您不相信,请阅读此主题 。

如果抛出exception,exception只会很昂贵。 我确信设置一个Try..Catch块有一些非常小的成本,但它远远超过了没有捕获exception并导致程序崩溃的成本。 正如其他人所指出的那样,Try..Catch块只应用于特殊情况。

try块的开销非常低,因此如果没有抛出exception,那么应该没有明显的惩罚。 抛出exception时发生的主要开销是发生寻找处理程序的堆栈遍历 – 因为您将exception缓存到如此接近源,我怀疑会出现很多性能问题。 理想情况下,虽然您可以事先正确validation输入,但电子邮件validation相当复杂,因此在这种情况下可能不值得。

如果抛出exception,它只是昂贵的,但这不是使用exception作为正常流控制的借口。

如果您可以预先validation某些内容以避免首先发生exception,那么请执行此操作。 例如,而不是你发布的东西,这样的东西会更好:

 string invalidAddress = "notvalid@@@@@@lolzors.bomb"; return MailAddressValidator.IsValid(invalidAddress ); // doesn't cause exception 

该规则的例外是当你必须滚动自己的复杂方法版本时(例如在基类库中找不到没有TryParse方法的东西),只是为了避免在宏大的方案中出现exception。事情, 无所谓

如果您不确定,请使用代表性数据进行配置。 如果用户每隔一秒在客户端应用程序表单中输入数据,则无关紧要。 但是,如果它是用于处理可能来自任何地方的数千个电子邮件地址的服务,那么您应该确定您的假设。

通常,现代编译器仅对try块施加最小成本,除非抛出exception。 它们仍然不应该用于程序流控制,因为它们不像标准流程结构那么明显。 exception基本上等同于COME FROM语句。

虽然你永远不应该使用try..catch进行程序流控制,但我不知道任何性能问题如果代码中没有实际抛出任何exception

这是依赖于语言的,但据我所知,如果没有抛出exception,那么使用try / catch几乎没有性能成本。

因此,在您使用预先validation的电子邮件地址的示例中,您拥有的内容很好。