静态构造函数会降低访问静态方法的性能吗?

发布于 2024-12-15 07:17:36 字数 954 浏览 0 评论 0原文

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

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

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

这是一个例子来说明我的问题。采用独立方法并将其放入单独的静态类中会有什么好处吗?这样,它就不必检查静态 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; }
}

以下是 C# 规范中关于静态构造函数的引用

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

  • 创建该类的实例。
  • 引用该类的任何静态成员。

A static constructor is executed the first time you access a static member. Knowing this, I have several questions:

  • Does this mean that every time I access a static method, the runtime must check if the static constructor has been called?
  • Does this incur a performance hit?
  • Do "constructor-less" static classes avoid this performance hit?

[EDIT]: I would like to clarify that I'm NOT concerned with micro-optimization.
I am asking this question because it is a design decision. If a static constructor incurs a performance hit, then I will design my code with that in mind, and will be more aware of the decisions that may affect performance.

Here's an example to illustrate my question. Would there be any benefit of taking the Independent method and putting it in a separate static class? That way, it would not have to check if static Test had been initialized. [Update See my answer below for a better, simpler example].

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 from the C# specification about the static constructor:

The execution of a static constructor is triggered by the first of the
following events to occur within an application domain:

  • An instance of the class is created.
  • Any of the static members of the class are referenced.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

盗心人 2024-12-22 07:17:37

由于缺乏答案,在@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; }
}

编译发布,使用 .NET 4.0,结果非常一致:

╔═════════════╦══════════════════╦═════════╦═══════════════╗
║ Iterations: ║ With Constructor ║ 4513 ms ║ Improvement:  ║
║ 1000000000  ║ No Constructor   ║ 3072 ms ║ 33%           ║
╚═════════════╩══════════════════╩═════════╩═══════════════╝

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

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

  • 如果静态构造函数不存在,则该方法不会产生性能影响。

Due to the lack of answers, and under @Jobo's direction, I decided to test this for myself.

Here are my test classes:

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

Compiled for Release, using .NET 4.0, the results were very consistent:

╔═════════════╦══════════════════╦═════════╦═══════════════╗
║ Iterations: ║ With Constructor ║ 4513 ms ║ Improvement:  ║
║ 1000000000  ║ No Constructor   ║ 3072 ms ║ 33%           ║
╚═════════════╩══════════════════╩═════════╩═══════════════╝

Therefore, I'm going to answer my own questions:

  • If a static constructor exists, then a static method will incur a (microscopic) performance hit, because the beforefieldinit flag must always be checked.

  • If a static constructor does not exist, then the method will not incur the performance hit.

黎歌 2024-12-22 07:17:37

为什么不自己测试一下呢?

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

使用 http://msdn.microsoft.com/en-us/ Library/system.diagnostics.stopwatch.aspx 用于测量。

我的猜测是这并不重要...

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

Why not test it yourself?

Call your Independent method a number of times like specified above.
Then make an own static class with the same method and call it the same number of times.

Use http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx for measuring.

My guess would be it won´t matter...

You could also write something to Console in your static Constructor to check if had been called.
Finding out for yourself will last longer than some theroetical answer, just my 2 cents.

七颜 2024-12-22 07:17:37

静态构造函数会降低第一个方法调用者的性能。实际上,第一个调用者被更改为测试静态构造函数是否已被调用,但其他调用者是否不受影响。

static constructor can reduce performance of the first method caller. Indead, first caller is changed to test if static constructor is already called but other caller if not affected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文