请求允许或道歉

本文关键字:道歉 请求 | 更新日期: 2023-09-27 17:58:47

我来自python背景,那里经常说道歉比请求许可更容易。具体给出两个片段:

if type(A) == int:
  do_something(A)
else:
  do_something(int(A))
try:
  do_something(A)
except TypeError:
  do_something(int(A))

然后,在大多数使用场景下,当A通常是一个整数时(假设do_something需要一个整数作为输入,并且会很快引发它的异常),第二种情况会更快,因为您在每个执行循环中都会丢失逻辑测试,而代价是更昂贵的异常,但频率要低得多。

我想检查的是,这在C#中是否属实,或者与异常相比,逻辑测试是否足够快,从而使这成为一个小问题?

哦,我只对发布性能感兴趣,对调试不感兴趣。


好吧,我的例子太模糊了,试试这个:

天真的解决方案:

return float(A) % 20 # coerse A to a float so it'll only fail if we actually don't
                     # have anything that can be represented as a real number.

基于逻辑的解决方案:

if isinstance(A, Number): # This is cheaper because we're not creating a new
    return A % 20         # object unless we really have to.
else:
    return float(A) %20

基于异常的解决方案:

try: # Now we're doing any logical tests in the 99% of cases where A is a number
  return A % 20
except TypeError:
  return float(A) % 20

使用FSO、数据库连接或网络上的东西的例子更好,但对于一个问题来说有点冗长。

请求允许或道歉

可能不会。NET异常相对昂贵。

由于这个原因,一些.NET函数同时提供了这两种变体。(通常推荐返回成功代码的int.TryParse,因为它比失败时抛出异常的int.Parse快)

但唯一重要的答案是你自己的分析数据告诉你什么。如果你需要表现,那么你需要衡量,衡量,衡量。

因为在我的计算机上,在my的code和my版本的.NET框架上,在这个时间可能不是你的计算机上最快的,在阅读你的1代码和你的.NET框架版本时。

.NET中的异常相当严重,因此C#的理念是只在异常情况下使用异常,而不用于程序流。

C#中的原理也适用于在使用之前检查从外部代码接收到的所有输入。例如:

public void Foo(int i)
{
    if (i == 0)           // validate input received from external code
    {
        throw new ArgumentOutOfRangeException("i");
    }
    DoSomething(i);
}
public void Foo()
{
    DoSomething(1);
}
internal void DoSomething(int i)
{
    Debug.Assert(i != 0); // validate that i is not zero in DEBUG build
                          // assume that i is not zero in RELEASE build
    Console.WriteLine(42 / i);
}

根据经验,不应将异常用于流控制。在特殊情况下使用异常——所以如果你确实期望A是int,那么你的第一种方法是明智的。如果它可以是int或字符串,那么第二个更可读。

就性能而言,发布构建是有区别的——合理的逻辑测试肯定足够快——所以我个人会追求可读性。

异常不应被用作"正常"执行流控制工具,是的,它们很昂贵。

无论如何,我认为你的问题有点误导,来自python。C#是(或曾经是?)一种静态类型的语言,这意味着许多类似于您所建议的场景都可以在编译时解决。

http://paltman.com/2008/01/18/try-except-performance-in-python-a-simple-test/有一个类似的测试,只是看has_key,我认为它比类型检查(稍微)贵一些。

对于存在密钥的大量迭代的情况(因此从不抛出异常),它的速度大约快25%,但仍然相当快。在钥匙不存在的地方,速度会慢1000%。

现在要记住,类型检查比查找键更快,而且.Net异常如前所述相当严重,在绝大多数情况下,你需要a是一个整数,然后它才可能有价值。

但是,正如贾尔夫之前提到的那样。试试看。