App*_*ker 20 .net c# performance operators
我正在使用C#(这个问题也适用于像C++这样的类似语言),我试图找出最快,最有效的增量方法.在我的游戏中,它不仅仅是一个或两个增量,而是每秒300个增量.就像屏幕上每个精灵的帧都在递增,我的RPG角色的速度和位置,相机的偏移等等.所以我在想,最有效的方法是什么?例如,y_pos我可以做的每次运动增加5 :
1.
Player.YPos += 5;
Run Code Online (Sandbox Code Playgroud)
2.
Player.YPos = Player.YPos + 5;
Run Code Online (Sandbox Code Playgroud)
3.
for (int i = 0; i < 5; i++)
{
Player.YPos++;
}
Run Code Online (Sandbox Code Playgroud)
哪个是最有效的(也是最快的)?
Jon*_*eet 90
(特定于C#作为C++的答案可能会有很大差异.)
1和2是等价的.
3肯定会慢一些.
话虽如此,每秒只做300次,你不会注意到任何差异.您是否知道计算机在一秒钟内可以在原始CPU +内存方面做多少?一般而言,您应该将代码编写为清晰度,这是最重要的事情.无论如何都要担心性能 - 但只有当你有办法测量它时,才能a)告诉你是否需要担心,以及b)是否有任何改变实际上改善了性能.
在这种情况下,我会说选项1是最清晰的,所以这就是我使用的.
Dav*_*nan 31
选项1和2将导致编译器生成相同的代码.选项3将慢得多.
这是一个i++比i += 1甚至更快的谬误i = i + 1.所有体面的编译器都会将这三个指令转换为相同的代码.
对于像添加这样的简单操作,编写最清晰的代码并让编译器担心使其快速.
Jac*_*lly 21
编译器应该为1和2生成相同的程序集,它可以在选项3中展开循环.当遇到这样的问题时,您可以使用一个有用的工具来实际测试正在发生的事情是查看编译器生成的程序集.在g ++中,这可以使用-S开关实现.
例如,选项1和2在使用命令编译时生成此汇编程序g++ -S inc.cpp(使用g ++ 4.5.2)
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
addl $5, -4(%rbp)
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
对于选项3,g ++产生效率明显较低的汇编程序:
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $0, -8(%rbp)
jmp .L2
.L3:
addl $1, -4(%rbp)
addl $1, -8(%rbp)
.L2:
cmpl $4, -8(%rbp)
setle %al
testb %al, %al
jne .L3
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
但是通过优化(偶数-O1),g ++可以为所有3个选项生成:
main:
.LFB0:
.cfi_startproc
leal 5(%rdi), %eax
ret
.cfi_endproc
Run Code Online (Sandbox Code Playgroud)
g ++不仅可以在选项3中展开循环,而且还使用lea指令在单个指令中进行添加,而不是使用mov.
因此,g ++将始终为选项1和2生成相同的程序集.只有在明确打开优化(这是您可能期望的行为)时,g ++才会为所有3个选项生成相同的程序集.
(看起来你应该能够检查由C#生成的程序集,虽然我从来没有尝试过)