局部变量初始化为 null 会影响性能吗?

发布于 2024-10-13 16:25:06 字数 938 浏览 3 评论 0原文

让我们比较两段代码:

String str = null;
//Possibly do something...
str = "Test";
Console.WriteLine(str);

String str;
//Possibly do something...
str = "Test";
Console.WriteLine(str);

一直认为这两段代码是相等的。但是在我构建这些代码(检查了优化的发布模式)并比较生成的 IL 方法后,我注意到第一个示例中还有两个 IL 指令:

第一个示例代码 IL:

.maxstack 1
.locals init([0]字符串str)
IL_0000:ldnull
IL_0001:stloc.0
IL_0002:ldstr“测试”
IL_0007:stloc.0
IL_0008:ldloc.0
IL_0009: 调用 void [mscorlib]System.Console::WriteLine(string)
IL_000e: ret

第二个示例代码 IL:

.maxstack 1
.locals init([0]字符串str)
IL_0000:ldstr“测试”
IL_0005:stloc.0
IL_0006:ldloc.0
IL_0007: 调用 void [mscorlib]System.Console::WriteLine(string)
IL_000c: ret

这段代码可能是由 JIT 编译器优化的? 那么,用 null 初始化本地 bethod 变量是否会影响性能(我知道这是非常简单的操作,但无论如何),我们应该避免它吗? 预先感谢。

Lets compare two pieces of code:

String str = null;
//Possibly do something...
str = "Test";
Console.WriteLine(str);

and

String str;
//Possibly do something...
str = "Test";
Console.WriteLine(str);

I was always thinking that these pieces of code are equal. But after I have build these code (Release mode with optimization checked) and compared IL methods generated I have noticed that there are two more IL instructions in the first sample:

1st sample code IL:

.maxstack 1
.locals init ([0] string str)
IL_0000: ldnull
IL_0001: stloc.0

IL_0002: ldstr "Test"
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: call void [mscorlib]System.Console::WriteLine(string)
IL_000e: ret

2nd sample code IL:

.maxstack 1
.locals init ([0] string str)
IL_0000: ldstr "Test"
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call void [mscorlib]System.Console::WriteLine(string)
IL_000c: ret

Possibly this code is optimized by JIT compiller?
So does the initialization of local bethod variable with null impacts the performence (I understand that it is very simple operation but any case) and we should avoid it?
Thanks beforehand.

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

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

发布评论

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

评论(3

凉城凉梦凉人心 2024-10-20 16:25:06

http://www.codinghorror。 com/blog/2005/07/for-best-results-dont-initialize-variables.html

从文章中总结,在运行各种基准测试后,将对象初始化为一个值(作为定义的一部分,在类的构造函数中,或作为初始化方法的一部分)在 .NET 1.1 和 2.0 上可能会慢大约 10-35%。较新的编译器可能会优化定义的初始化。本文最后建议作为一般规则避免初始化。

http://www.codinghorror.com/blog/2005/07/for-best-results-dont-initialize-variables.html

To summarize from the article, after running various benchmarks, initializing an object to a value (either as part of a definition, in the class' constructor, or as part of an initialization method) can be anywhere from roughly 10-35% slower on .NET 1.1 and 2.0. Newer compilers may optimize away initialization on definition. The article closes by recommending to avoid initialization as a general rule.

夏了南城 2024-10-20 16:25:06

正如 Jon.Stromer.Galley 的链接指出的那样,它稍微慢一些。但差异却小得惊人。可能是纳秒的量级。在这个级别上,使用 C# 等高级语言的开销使任何性能差异都相形见绌。如果性能是一个很重要的问题,那么您也可以使用 C 或 ASM 或其他语言进行编码。

就成本与收益而言,编写清晰代码的价值(无论这对您意味着什么)将远远超过 0.00001 毫秒的性能提升。这就是 C# 和其他高级语言存在的首要原因。

我知道这可能是一个学术问题,而且我并不低估理解 CLR 内部结构的价值。但在这种情况下,关注的焦点似乎是错误的。

It is slightly slower, as Jon.Stromer.Galley's link points out. But the difference is amazingly small; likely on the order of nanoseconds. At that level, the overhead from using a high-level language like C# dwarfs any performance difference. If performance is that much of an issue, you may as well be coding in C or ASM or something.

The value of writing clear code (whatever that means to you) will far outweigh the 0.00001ms performance increase in terms of cost vs. benefit. That's why C# and other high-level languages exist in the first place.

I get that this is probably meant as an academic question, and I don't discount the value of understanding the internals of the CLR. But in this case, it just seems like the wrong thing to focus on.

殊姿 2024-10-20 16:25:06

如今(2019 年),.NET Framework 和 .NET Core 编译器都足够智能,可以优化不需要的初始化。 (以及无用的 stloc.0 - ldloc.0 对。)

两个版本都编译为

        .maxstack 8

        ldstr "Test"
        call void [System.Console]System.Console::WriteLine(string)
        ret

参见我的 SharpLab 实验作为参考。

当然,实现会发生变化,但贾斯汀的答案是永恒的:我出于好奇而进行了这个实验,在真实情况下关注代码的清晰度和表现力,而忽略了微观优化。

Today (2019) both the .NET Framework and the .NET Core compilers are smart enough to optimize unneeded initializations away. (Along with the useless stloc.0 - ldloc.0 pair.)

Both versions compile as

        .maxstack 8

        ldstr "Test"
        call void [System.Console]System.Console::WriteLine(string)
        ret

See my SharpLab experiment as reference.

But of course implementations change, but Justin's answer is timeless: I did this experiment out of curiosity, in a real situation focus on code clarity and expressiveness, and ignore micro-optimizations.

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