【问题标题】:Is an empty block optimized away? C#是否优化了空块? C#
【发布时间】:2011-06-02 04:59:04
【问题描述】:

我正在用 C# 开发一个游戏服务器,每个玩家每秒 3 到 5 次将特定数据包发送到我的服务器。我们将该数据包称为PacketA。除了确保我收到它之外,我不会对它做任何事情。

由于这个数据包被发送的最多,我想把它放在开关块的第一个,这样我就不必做太多不必要的比较了。编译器最终会优化它吗(这将导致我在 switch 块中进行所有比较?)

switch (packetId)
{
    case PacketID.PacketA: // I do not want to do anything here.
        break;             // Just avoid all other packet id comparisons.

    case PacketID.PacketB:
        HandlePacketB(data);
        break;

    case PacketID.PacketC:
        HandlePacketC(data);
        break;

    // ...

    case PacketID.PacketZ:
       HandlePacketZ(data);
       break;
}

如果编译器确实优化了这一点,我该如何更改我的代码,这样我就不必检查所有其他数据包 ID?

【问题讨论】:

    标签: c# compiler-optimization


    【解决方案1】:

    C# 中的switch 语句经过优化,可以非常快速地评估去向。它不会准确地阅读选项列表。相反,它会创建一个跳转列表,并对其进行优化以识别要执行的案例。这是一个包含更多信息的链接:

    http://www.dotnetperls.com/switch-char

    基本上,我建议您测试此语句与另一个语句相比的性能(例如,仅对第一个 case 执行 if 语句,然后在不是 @ 时执行 switch 语句987654327@)。我想最后switch 声明是要走的路。

    如果您决定通过反编译来深入了解您的应用程序,您可以使用 Telerik 的新(免费)工具:

    http://www.telerik.com/products/decompiling.aspx

    【讨论】:

    • 这将是我的答案。很多人推荐使用Dictionary<TKey, Action>,却不知道编译器在内部做了这种事情。我认为无论哪种方式,您都不会真正看到性能差异。
    【解决方案2】:

    反汇编您的代码并检查这种情况是否可用。 如果它不可用,则编译器对其进行优化。

    【讨论】:

    • 介意添加更多关于如何拆卸它的细节吗?反射器不再免费。
    • @icktoofay:ildasm 带有 VC。如果要反编译,请查看 ILSpy:wiki.sharpdevelop.net/ILSpy.ashx
    • 实际上是(他们更改了旧 v6 版本的条款,如果你有的话)。此外,还有免费的 JetBrains dotPeek,毕竟还有 ILDASM。
    猜你喜欢
    • 1970-01-01
    • 2013-08-06
    • 2014-04-18
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 2014-08-20
    • 2017-04-21
    • 2015-09-08
    相关资源
    最近更新 更多