C# 算法效率:我应该使用相等(=)还是不相等(!=)运算符?
我想知道下面两个选项中哪一个在速度方面效率最高。它们之间可能只有很小的区别(或者根本没有区别?),但由于我每天使用这段代码30次,我想知道这里的“最佳实践”是什么:) 备选案文1:C# 算法效率:我应该使用相等(=)还是不相等(!=)运算符?,c#,performance,C#,Performance,我想知道下面两个选项中哪一个在速度方面效率最高。它们之间可能只有很小的区别(或者根本没有区别?),但由于我每天使用这段代码30次,我想知道这里的“最佳实践”是什么:) 备选案文1: if (sender != null) LabelSave.Text = "Saved"; else LabelSave.Text = "Auto-Saved"; 备选案文2: if (sender == null) LabelSave.Text = "Auto-Saved"; else
if (sender != null)
LabelSave.Text = "Saved";
else
LabelSave.Text = "Auto-Saved";
备选案文2:
if (sender == null)
LabelSave.Text = "Auto-Saved";
else
LabelSave.Text = "Saved";
请不要考虑“sender”变量的值,这里真正的问题是“这两个变量之间最快的运算符是什么”=和“==”在c#?”我认为效率会随着变量类型的不同而变化,所以就像Eric说的,你真的需要测量它才能发现 然而,如果你问你应该用哪种方式写,我可以建议选择2(通常)更好。原因是,如果没有否定的话,阅读就少了一步。由于代码编写一次,阅读多次,我们几乎应该始终把可读性放在第一位。我们只有在证明有必要的情况下才能开始提高效率
有一本很棒的书叫做《这是我真正推荐的关于这类东西的书》。我认为效率会随着变量类型的不同而变化,所以就像Eric说的,你真的需要测量它来找出答案 然而,如果你问你应该用哪种方式写,我可以建议选择2(通常)更好。原因是,如果没有否定的话,阅读就少了一步。由于代码编写一次,阅读多次,我们几乎应该始终把可读性放在第一位。我们只有在证明有必要的情况下才能开始提高效率
有一本很棒的书叫做《这是我真正推荐的关于这类东西的书》。两个比较
sender==null
和sender!=空
花费相同的时间*
最佳做法是使用可读性或可理解性最好的方法,这取决于具体情况
例如:
if (condition) {
...
lots_of_code();
...
return;
}
short_code();
return;
如果将其写为:
if (!condition) {
short_code();
return;
}
...
lots_of_code();
...
return;
在第二个版本中,更多的代码位于较低的范围级别,因此通常更容易理解
*注意:如果您要运行这种检查数百万次,并且它确实成为一个性能问题(不太可能),那么您需要稍微了解一下编译器是如何工作的。大多数编译器采用以下方式:
if (condition) {
do_something();
} else {
do_other_thing();
}
return;
并制作如下说明:
evaluate condition
jump_if_false ELSECODE
do_something()
return
ELSECODE:
do_other_thing()
return
当条件为真时跳过跳转通常比在条件为假时执行跳转稍微便宜。但这取决于if
语句之后立即执行的操作。编译器通常会在编译时猜测哪个分支更有可能,并相应地安排代码,而CPU可能会在运行时进行分支预测,以不同的方式对其进行优化。对于某些语言/编译器,您可以给出一个提示,说明条件
极有可能发生或极不可能发生
99.99%的时候你应该完全忽略这一点,但在一些罕见的情况下(比如你试图编写操作系统或模拟器的一部分,或者为嵌入式设备编写的东西),这一点变得很重要。这两个比较sender==null
和sender!=空
花费相同的时间*
最佳做法是使用可读性或可理解性最好的方法,这取决于具体情况
例如:
if (condition) {
...
lots_of_code();
...
return;
}
short_code();
return;
如果将其写为:
if (!condition) {
short_code();
return;
}
...
lots_of_code();
...
return;
在第二个版本中,更多的代码位于较低的范围级别,因此通常更容易理解
*注意:如果您要运行这种检查数百万次,并且它确实成为一个性能问题(不太可能),那么您需要稍微了解一下编译器是如何工作的。大多数编译器采用以下方式:
if (condition) {
do_something();
} else {
do_other_thing();
}
return;
并制作如下说明:
evaluate condition
jump_if_false ELSECODE
do_something()
return
ELSECODE:
do_other_thing()
return
当条件为真时跳过跳转通常比在条件为假时执行跳转稍微便宜。但这取决于if
语句之后立即执行的操作。编译器通常会在编译时猜测哪个分支更有可能,并相应地安排代码,而CPU可能会在运行时进行分支预测,以不同的方式对其进行优化。对于某些语言/编译器,您可以给出一个提示,说明条件
极有可能发生或极不可能发生
99.99%的情况下,您应该完全忽略这一点,但在某些罕见的情况下(例如,如果您试图编写操作系统或模拟器的一部分,或为嵌入式设备编写的东西),这一点变得很重要。您编写的代码是双向的。如果您想知道哪个更快,请采取下一步:双向运行。然后你就会知道哪一个更快了。你有没有在代码上遇到任何问题?您是否发现该特定产品线存在任何性能问题?这两者之间的差别可能很小,但在现实世界中,你们根本不应该在意。还要记住,“一天30次”本质上就是“一天零次”。你的机器每秒可以做40亿次运算。如果你每天不做数万亿次,不要担心它的速度有多快。@sphax:计算机中几乎没有比“这是零吗?”和“这不是零吗?”更快的操作,费用不在计算中;代价是芯片上的分支预测器是否猜错了。如果你想从先验的角度来回答哪个更快的问题,而不是测量并找出答案,你就必须从相当深的层次来研究芯片架构。更一般地说,你正在走纳米级优化的道路。这是一条不好的道路。获得高性能应用程序的方法是:设定一个性能目标,仔细衡量您的性能与t