在C++中,先检查变量再设置它的值是否更好?

10

如果我有一个布尔变量和一些可能会改变它的代码,然后我想将其设置为true,那么我应该检查它是否为false吗?

例如:

bool b = false;
// Some code
// Here "b" can be true or false
if (cond) {
    b = true;
}

vs

的翻译是:vs。
bool b = false;
// Some code
// Here `b` can be `true` or `false`
if (cond && !b){
    b = true;
}

哪种更快?

注意:

我之所以问这个问题,是因为下面这个实现埃拉托斯特尼筛法(Sieve of Eratosthenes): http://bloc.gerardfarras.com/wp-content/uploads/2011/12/erastotenes.txt

if (( i % divisor == 0 ) && ( numsprimers[i] == 0 )) {
    numsprimers[i] = 1;
}

(如果numsprimers[i]==1,则表示i不是质数。如果它是0,则可以是质数也可能不是)


1
另一种思考方式是:“为什么要检查?直接覆盖!” - Mysticial
@Mysticial,我记得一个程序通过检查布尔值并覆盖它来获得了巨大的速度增加,而不是仅仅覆盖它。虽然我没有基准测试,但也许值得做一下... - Seth Carnegie
@SethCarnegie 这是一个用户定义的类型吗? - Mysticial
@Mysticial 不是的,它是一个布尔值,在一个内部循环中。 - Seth Carnegie
1
@SethCarnegie 这很有趣... - Mysticial
显示剩余4条评论
2个回答

5

这可能有点吹毛求疵,但一般来说最好只更改值。

检查和设置一个值的开销大致相同,那么为什么在某些情况下还要两者都做呢?

现在,如果你想知道是否应该覆盖某个自定义类型(比如一个包含10万个单词的列表)或者你应该先检查它是否需要覆盖(比如通过简单地检查布尔值或时间戳),那么你应该首先检查,因为检查布尔值或时间戳的成本比将这么多单词写入内存要少得多。

当然,这完全取决于各种因素,例如你正在编辑的内存是否在缓存中、"检查"的开销有多大、你需要覆盖该值的频率与它不需要被覆盖的频率以及内存的大小等。


1
鉴于你的筛法,由于可能的值只有0和1,我看不出在更改numsprimers[i]的值之前检查它的价值的理由。这最终会导致几个指令:获取nuprimers[i]的值。将其与0进行比较。如果为0,则跳转到代码的其他位置。 - Ben
很久以前,也许我仍然能得到一个答案: 在我的情况下,大多数元素仍将具有所需的值= true。 因此,检查值是否仍为true可以避免再次将其设置为true。 如果我们总共谈论数千万个元素,那么“在不检查之前只更改值”仍然是一种相等快速的操作吗? - Kaspatoo
2
我觉得很奇怪,这里没有人谈论多线程。据我所知(无论锁定与否),写入会使缓存行“脏”,并强制所有其他核心重新加载它,而读取则不会。一个显而易见的问题是,将相同的值写入缓存是否会将其标记为脏,并强制重新加载其他核心缓存,在某些情况下,“仅覆盖”选项肯定比检查和覆盖选项慢(因为检查会保留其他核心的缓存)。 - Cookie

0

这样怎么样:

if ( b = !!cond ) {

}

在这里,您检查条件并将值应用于b,如果b需要有一个值。如果您希望b保持为真,则建议使用其他示例之一。这不应该有任何区别。


但是也许“cond”为“false”,而“b”为“true”。我希望“b”保持不变。 - Oriol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接