要求许可或道歉?

时间:2011-06-10 11:14:21

标签: c# python performance rules-of-thumb

我来自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,数据库连接或网络上的内容的示例更好,但对于一个问题有点啰嗦。

5 个答案:

答案 0 :(得分:14)

可能不是。 .NET异常相对昂贵。

出于这个原因,有几个.NET函数提供了两种变体。 (int.TryParse,通常建议返回成功代码,因为它比失败时抛出异常的int.Parse更快)

但唯一重要的答案是您自己的分析数据告诉您的内容。 如果您需要表现,那么您需要进行衡量,衡量和衡量。

因为在我的计算机上使用我的代码,使用我的版本的.NET框架, 时间可能不是计算机上最快的,使用 代码,在您阅读时使用您的.NET框架版本。

答案 1 :(得分:7)

.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);
}

答案 2 :(得分:6)

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

在性能方面,发布版本存在差异 - 合理的逻辑测试肯定足够快 - 所以我个人认为这是可读性的。

答案 3 :(得分:2)

异常不应该用作“正常”执行流程控制工具,是的,它们很昂贵。

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

答案 4 :(得分:0)

http://paltman.com/2008/01/18/try-except-performance-in-python-a-simple-test/有一个类似的测试,除了查看has_key,我希望(稍微)比类型检查更贵。

对于存在密钥的大量迭代(因此永远不会抛出异常),它的速度提高了约25%,但仍然相当快。如果密钥永远不存在,那么它的速度要慢1000%。

现在请记住,类型检查比查找密钥更快,如上所述,.Net异常是相当重量级的,你需要A在绝大部分时间都是整数可能值得。

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