编译成 MSIL 的代码大小是否一定与代码速度相关?
我一直在 Visual Basic 中尝试不同类型的本机代码操作,然后使用 Reflector 检查代码以查看生成的 MSIL 类型。例如,我想知道,在一行 If-Then-Else 中与拆分为多行的 If-Then-Else 不同,即。
If x > y Then x Else y
结果
If x > y Then
x
Else
y
End If
这两个编译为相同的 MSIL。然后我想知道新的 If 运算符,类似于旧的 IIf 函数。需要注意的是,IIf 确实是一个函数,因此会产生函数调用的开销,因此虽然它看起来很简洁,但它也有其缺点。此外,它在返回值之前评估 TruePart 和 FalsePart,即。不会短路,因此可能会出现意外行为。因此,我将坚持使用 If 运算符。
事实证明,当您使用 If 运算符来实现相同的功能时,就像这样......
If(x > y, x, y)
生成的 MSIL 更小并且看起来更高效。这让我想到了这个主题中的问题。
编译成 MSIL 的代码大小是否一定与代码速度相关?
I have been playing around with different types of native code operations in Visual Basic and then inspecting the code with Reflector to see what kind of MSIL is produced. For example, I wondered, in a one line If-Then-Else different than an If-Then-Else split onto multiple lines, ie.
If x > y Then x Else y
vs.
If x > y Then
x
Else
y
End If
Turns out those two compile to the same MSIL. Then I wondered about the new If operator, similar to the old IIf function. It's important to note that indeed IIf is a function and so incurs the overhead of a function call, so while it seems concise, it has its drawbacks. Further, it evaluates both the TruePart and the FalsePart before returning a value, ie. not short-circuiting, so it can have unexpected behavior. So, I'll stick with the If operator.
Turns out, when you use the If operator for the same functionality, like so...
If(x > y, x, y)
The produced MSIL is much smaller and seemingly more efficient. Which leads me to the question in the subject.
Does the size of compiled code into MSIL necessarily correlate to code speed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在非常简单的层面上,执行更多指令会比执行更少指令花费更长的时间,但您不能仅仅说编译代码的大小与速度相关。
对于初学者来说,您的 MSIL 并不直接在计算机上运行,而是在运行时被 JIT 编译为实际的机器代码,并在此过程中可能进一步优化。
此外,代码的性质也会产生影响 - 执行简单算术运算的长代码可能比具有大量分支的较短代码运行得更快,这仅仅是因为处理器可能会错误预测分支,从而使管道停顿并减慢速度程序。
真正确定一段代码是否比另一段代码更快的唯一方法是在适当的目标环境中运行它并对其进行分析。
At a very simplistic level, having more instructions to execute is going to take longer than fewer, but you cannot just say the size of compiled code correlates to the speed.
For a starter, your MSIL isn't running directly on the machine but instead will be JIT compiled to actual machine code at runtime with potentially further optimisations in the process.
Also the nature of the code makes a difference - a long piece of code that does simple arithmetic operations may run quicker than a shorter bit of code with lots of branches simply because the processor may mis-predict the branch, stalling the pipeline and slowing the program.
The only way to be truly sure whether one bit of code is faster than another is to run it and profile it on the appropriate target environment.
就原始执行时间(不包括加载和 JIT 编译代码的开销)而言,没有相关性。
循环是可能执行很长时间的紧凑代码的主要示例。您可以编写一个永远不会终止的非常短的行:
您还可以编写复杂且长的代码,只要编译器允许(一旦 JIT 编译器完成它)几乎立即返回。你只需要比编译器更聪明:
所以,更长并不一定意味着更慢,尽管即时编译器可能需要更长的时间来编译代码,并且如果它加载代码可能需要更长的时间不在记忆中。
判断两种方案中哪一种更快的唯一方法是进行测量。大多数时候,无论如何,这并不重要。
As far as raw execution time (excluding overhead of loading and JIT-compiling the code), there is no correlation.
Loops are the prime example of compact code that may execute for a very long time. You can write a very short one liner that will never terminate:
You can also write code as complex and long as the compiler will allow that (once the JIT compiler is done with it) returns almost instantly. You only have to be smarter than the compiler:
So, longer doesn't necessarily mean slower, although it will probably take longer for the Just-In-Time compiler to compile the code, and it may take longer to load the code if it wasn't in memory.
The only way to tell which of two alternatives is faster, is to measure. And most of the time, it really doesn't matter anyway.
不会。一个典型的反例是循环展开,它以牺牲大小为代价来提高速度。
No. A typical counter-example is loop unrolling, which gains speed at the cost of size.