在C#中,当设置一个布尔变量的值为false
时,如果它是true
,我应该在设置之前检查它是true
还是true
刚设置好吗?
假设变量在50%的时间内为true
,检查它是有意义的,因为比较更快。如果变量在大多数情况下都是if (bVariable)
bVariable = false;
,我应该跳过比较吗?
方法1,先检查:
bVariable = false;
或方法2,只需设置:
{{1}}
在哪种条件方法2 首选,如果有的话?
答案 0 :(得分:8)
是什么让你认为比较更快?如果您编写的代码是在C编译器中完成的,则IF语句将被拆分为至少两条指令 - 比较/分支指令和单个字上单个位的“set”指令。
“set”将编译为单个指令。您的“优化”可能会使您的程序运行速度变慢,并且会导致程序的可读性降低。只需设置变量,不要试图过度思考小事。
CPU与数据库不同。您不需要为数据修改支付高额罚金。您在前往主内存和分支(如果声明)时会受到高额罚款。分支的性价比是因为pipelining CPU在分支指令做出决定之前实际开始在分支之后开始执行指令! (我知道,这种说法有点令人兴奋)。但这意味着CPU必须花费资源“guessing”你的IF语句的结果是什么。如果它猜错了,它必须“扔掉”它猜测在分支后执行的所有指令的结果,然后再试一次。这不好。这就是分支机构昂贵的原因。
这个特定故事的寓意并不是你永远不应该优化,而是你应该永远不要在没有完全理解优化的含义的情况下进行优化。在这种情况下,如果您使用选项1,您可能最终得到一个较慢的应用程序,其启动可读性较差。
实际上,如果你真的对这类事情感兴趣,你应该肯定拿起Code Complete的副本。它充满了关于这类事情的讨论,而且写得非常精彩。
答案 1 :(得分:3)
不要让生活复杂化。只需设置它。无论如何,首先检查它实际上更昂贵,因为你现在必须在发回新值之前从RAM(或缓存)中剔除现有值。
(感谢Colin Mackay ......)由于分支错误预测,测试首先也会导致管道失速处罚。
答案 2 :(得分:3)
在C#中答案是:方法2总是首选。由于这是一个非常简单的优化,如果方法1真的更快,编译器就会这样做。
编辑:
Donald Knuth对你的方法1有一些建议,例如“过早优化是所有邪恶的根源”,“代码首先应由人类阅读,然后是机器”。
答案 3 :(得分:1)
这看起来像是一个微优化,我真的认为编译器会为你优化这一点。
但是,如果您希望最终值为false
,无论如何,我想简单地将其分配给false
更有意义。我的意思是为什么要检查你是否真的不需要关心这个价值。
答案 4 :(得分:1)
我认为性能差异是如此微不足道,只是将事情设置为假。
如果为false,则会再次设置为false。 如果是,则将其设置为false。
在代码结束时,无论如何变量都是假的。
通过将其设置为false,无论如何都要使意图更清晰。阅读代码的任何其他人都会立即看到在该部分代码的末尾所有实例中的值都将为false。如果你有一个if语句,他们将不得不考虑更难。
对于单独的维护,我建议将值设置为false,而不管其原始值是什么,因为它最终总是为假。
答案 5 :(得分:1)
方法2应该是首选,因为它更简单地表达了相同的结果,使得它更容易阅读,正如其他人所说的那样 - 对于简单的事情,这种易读性远比那些极其小的性能问题重要。
但是,bVariable
可能是一个属性,在这种情况下设置它可能会带来其他副作用 - 无论是在性能还是结果方面,都可能。
答案 6 :(得分:0)
进行比较的唯一原因是,如果您需要在值更改时执行额外的逻辑。
如果您只打算分配它,如果您进行额外检查,很可能会损害性能。
答案 7 :(得分:0)
过早优化是万恶之源。你无法说服我这个“优化”会给你任何的性能提升
答案 8 :(得分:0)
这里的性能问题并不重要,因为像上面那样简单的if语句基本上接近处理器的no-op。更重要的是,您的代码明确地向后来的读者传达了它的意图!
托马斯