代码之家  ›  专栏  ›  技术社区  ›  Joe Huha

.net JIT编译器二次编译大型方法

  •  1
  • Joe Huha  · 技术社区  · 10 年前

    我希望在IL中生成一个大型switch语句,然后JIT编译并运行它。JIT编译器所花费的时间似乎比代码大小的二次方稍差。将输入大小加倍将使编译时间乘以4到6之间的系数。每个案例都有10条说明。

    请有人告诉我,是否有一种方法可以让JIT编译器占用O(n^(1+epsilon))时间(例如,线性、n log n或其他基本上是次二次的)?我并不担心结果质量下降。

    产生巨大开关的原因在这里并不重要。我可以通过嵌套开关来解决这个问题。我不能仅仅把键放进字典,因为它需要映射到函数,而且很多小函数也不利于可扩展性(可能不如大型开关那么糟糕,但这仍然是一种泛火的情况,盲目地将一个换成另一个可能不会带来巨大的空间)。

    1 回复  |  直到 10 年前
        1
  •  1
  •   Mark Hurd    10 年前

    我猜JITter正在尝试查找常见的子表达式等。我认为将其转换为 Dictionary(Of <lookupType>, Func(Of <ParameterTypes>, <ReturnType>)) 因为这也意味着JITter只编译实际使用的案例。当然,如果您的单个代理最终基于大型闭包,这可能会解释您最初的性能问题的一部分。

    或者,为了部分确认JITter正在做什么,不要更改 switch 代码,但在每种情况下都调用一个评估该情况结果的委托。这将迫使JITter不内联调用,因此不会尝试许多优化。事实上,您可能可以避免委托调用,只需在子例程中为每个案例提供 System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.NoInlining) 属性