【问题标题】:Can a static constructor reduce the performance of accessing static methods?静态构造函数会降低访问静态方法的性能吗?
【发布时间】:2011-12-29 06:28:06
【问题描述】:

第一次访问静态成员时会执行静态构造函数。知道了这一点,我有几个问题:

  • 这是否意味着每次访问静态方法时,运行时都必须检查是否调用了静态构造函数?
  • 这会影响性能吗?
  • “无构造函数”静态类能否避免这种性能损失?

[编辑]:我想澄清一下,我不关心微优化。
我问这个问题是因为这是一个设计决定。如果静态构造函数导致性能下降,那么我将在设计代码时考虑到这一点,并且会更加了解可能影响性能的决策。

这里有一个例子来说明我的问题。采用Independent 方法并将其放在单独的静态类中会有什么好处吗?这样,它就不必检查静态Test 是否已初始化。 [更新请参阅下面的答案以获得更好、更简单的示例]。

static class Test {
  // Static constructor with dependent method:
  static int x;
  static Test() { x = 5; }
  static int Dependent() { return x; }

  // Static, independent method:
  static int Independent(int y) { return y+1; }
}

Here's the quote 来自关于静态构造函数的 C# 规范:

静态构造函数的执行由第一个触发 在应用程序域中发生以下事件:

  • 创建了一个类的实例。
  • 类的任何静态成员都被引用。

【问题讨论】:

  • 我读过那篇文章,但它肯定与我的问题不同。它比较了类型初始化静态构造函数的性能。我有兴趣知道静态构造函数是否会减慢访问方法的速度。我重新阅读了“重复”,包括所有答案和链接,但我的问题仍然没有答案!
  • 我认为这是在字段访问上,而不是在方法调用上。但是,是的,在某些情况下可能会出现明显的性能下降。
  • @HenkHolterman 我通常批评过早的优化。但是,我对开发良好的设计模式更感兴趣,如果已知静态构造函数会导致性能下降,那么设计可能会导致性能下降的静态方法并不是一个很好的做法。

标签: c# .net performance static static-constructor


【解决方案1】:

为什么不自己测试呢?

像上面指定的那样多次调用您的 Independent 方法。 然后用相同的方法创建一个自己的静态类,并调用相同的次数。

使用http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx 进行测量。

我的猜测是没关系...

您还可以在静态构造函数中向控制台写入一些内容,以检查是否已被调用。 自己找出答案会比一些理论答案持续更长时间,只是我的 2 美分。

【讨论】:

  • 我想我会的。我真的很惊讶没有一个众所周知的答案。
  • @Scott 没有一个众所周知的答案,因为这很可能不是任何人的瓶颈。它甚至有可能删除该构造函数,而是将 X 的值默认为 5。
  • @Rangoric 我没有在我的 OP 中提到这一点(它现在在那里),但我对性能的兴趣不如对设计决策的兴趣。在设计静态方法时,了解可能的性能影响肯定会有所帮助,在这种情况下,拥有良好的设计模式将有助于避免这些影响。
【解决方案2】:

由于缺乏答案,在@Jobo 的指导下,我决定自己测试一下。

这是我的测试类:

static class WithConstructor {
    static WithConstructor(){ }
    public static int Square(int x){ return x*x; }
}
static class NoConstructor {
    public static int Square(int x){ return x*x; }
}

为Release编译,使用.NET 4.0,结果非常一致:

╔═════════════╦══════════════════╦═════════╦══════ ═════════╗ ║ 迭代: ║ 使用构造函数 ║ 4513 ms ║ 改进: ║ ║ 1000000000 ║ 无构造函数 ║ 3072 ms ║ 33% ║ ╚═════════════╩══════════════════╩═════════╩══════ ═════════╝

因此,我将回答我自己的问题:

  • 如果存在静态构造函数,则静态方法将导致(微观)性能下降,因为必须始终检查 beforefieldinit 标志。

  • 如果静态构造函数不存在,则该方法不会导致性能损失。

【讨论】:

    【解决方案3】:

    静态构造函数会降低第一个方法调用者的性能。 Indead,将更改第一个调用者以测试是否已调用静态构造函数,但如果不影响其他调用者。

    【讨论】:

      猜你喜欢
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多