哪个更快? ++、+= 或 x + 1?
我正在使用 C#(这个问题对于 C++ 等类似语言也有效),我试图找出最快、最有效的增量方法。在我的游戏中,这不仅仅是一两个增量,每秒大约有 300 个增量。就像屏幕上每个精灵的帧数都在递增一样,我的RPG角色的速度和位置,相机的偏移等等。所以我在想,什么方法是最有效的?例如,我可以在每次移动时增加 5 y_pos
:
1.
Player.YPos += 5;
2.
Player.YPos = Player.YPos + 5;
3.
for (int i = 0; i < 5; i++)
{
Player.YPos++;
}
哪个是最有效(且最快)的?
I am using C# (This question is also valid for similar languages like C++) and I am trying to figure out the fastest and most efficient way to increment. It isn't just one or two increments, in my game, its like 300 increments per second. Like the Frames of every sprite on the screen are incrementing, the speed and positions of my rpg character, the offset of the camera etc. So I am thinking, what way is the most efficient? e.g for incrementing 5 y_pos
on every movement I can do:
1.
Player.YPos += 5;
2.
Player.YPos = Player.YPos + 5;
3.
for (int i = 0; i < 5; i++)
{
Player.YPos++;
}
Which is the most efficient (and fastest)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
选项 1 和 2 将导致编译器生成相同的代码。选项 3 会慢很多。
认为
i++
比i += 1
甚至i = i + 1
更快是一个谬论。所有像样的编译器都会将这三个指令转换为相同的代码。对于加法这样的琐碎操作,编写最清晰的代码,让编译器担心它的速度。
Options 1 and 2 will result in identical code being produced by the compiler. Option 3 will be much slower.
It's a fallacy that
i++
is faster thani += 1
or eveni = i + 1
. All decent compilers will turn those three instructions into the same code.For such a trivial operation as addition, write the clearest code and let the compiler worry about making it fast.
编译器应该为1和2生成相同的程序集,并且它可能展开选项3中的循环。当遇到这样的问题时,您可以使用一个有用的工具来根据经验测试发生的事情是查看编译器生成的程序集。在 g++ 中,这可以使用
-S
开关来实现。例如,当使用命令
g++ -S inc.cpp
(使用 g++ 4.5.2)编译时,选项 1 和 2 都会生成此汇编程序g++ 为选项 3 生成效率明显较低的汇编程序:
但是通过对(甚至 -O1)的优化,g++ 会为所有 3 个选项生成此内容:
g++ 不仅展开选项 3 中的循环,而且还使用 lea 指令 在一条指令中进行加法,而不是用
mov
胡闹。因此,g++ 将始终为选项 1 和 2 生成相同的程序集。仅当您显式打开优化时,g++ 才会为所有 3 个选项生成相同的程序集(这是您可能期望的行为)。
(看起来您应该能够 也检查 C# 生成的程序集,尽管我从未尝试过)
The compiler should produce the same assembly for 1 and 2 and it may unroll the loop in option 3. When faced with questions like this, a useful tool you can use to empirically test what's going on is to look at the assembly produced by the compiler. In g++ this can be achieved using the
-S
switch.For example, both options 1 and 2 produce this assembler when compiled with the command
g++ -S inc.cpp
(using g++ 4.5.2)g++ produces significantly less efficient assembler for option 3:
But with optimisation on (even -O1) g++ produces this for all 3 options:
g++ not only unrolls the loop in option 3, but it also uses the lea instruction to do the addition in a single instruction instead of faffing about with
mov
.So g++ will always produce the same assembly for options 1 and 2. g++ will produce the same assembly for all 3 options only if you explicitly turn optimisation on (which is the behaviour you'd probably expect).
(and it looks like you should be able to inspect the assembly produced by C# too, although I've never tried that)
它们是相同的:
ILSpy 中的上述代码是:
所有这些的 IL 也相同(在发布模式下) :
They are same:
The above code in ILSpy is:
Also the IL for all these is same as well (In Release mode):
选项 1 和 2 编译后将产生相同的代码。选项 3 会慢得多,因为它会导致涉及的 for 循环代码更多。
Options 1 and 2 will result in identical code after being compiled. Option 3 will be much slower as its results in more code for the for loop involved.
(针对 C# 的答案可能会有很大差异,因为 C++ 可能会有很大差异。)
1 和 2 是等效的。
3肯定会慢一些。
话虽如此,每秒仅执行 300 次,您不会注意到任何差异。您是否知道计算机在一秒钟内可以用原始 CPU + 内存执行多少操作?一般来说,您编写代码时应该将清晰性作为最重要的事情。无论如何都要担心性能 - 但只有当您有办法衡量它时,才能a)判断您是否需要担心,以及b)任何更改是否真正提高了性能。
在这种情况下,我会说选项 1 是最清晰的,所以我会使用它。
(Answer specific to C# as C++ may vary significantly.)
1 and 2 are equivalent.
3 would definitely be slower.
Having said that, doing this a mere 300 times a second, you wouldn't notice any difference. Are you aware of just how much a computer can do in terms of raw CPU+memory in a second? In general, you should write code for clarity as the most important thing. By all means worry about performance - but only when you have a way to measure it, in order to a) tell whether you need to worry, and b) whether any changes actually improve the performance.
In this case, I'd say that option 1 is the clearest, so that's what I'd use.