如果我使用hte以下代码,编译器是否会像开关结构一样优化它,它使用二叉树来搜索值?
if ( X == "aaaa" || X == "bbbb" || X == "cccc" || X == "dddd" )
{
}
else if ( X == "abcd" || X == "cdef" || X == "qqqq" )
{
}
这只是一个例子,引号中没有什么模式
更新
好的,X是一个字符串,但我认为这并不重要,我只是想知道,当if
内的所有内容都是关于单个变量的时候,它会被优化。
答案 0 :(得分:3)
这些值将一个接一个地进行比较,因为它是||
或短路运算符的要求。所以,这里会发生两件事:
例如:
int hello() {
std::cout<<"Hello";
return 10;
}
int world() {
std::cout<<"World";
return 11;
}
int hello2() {
std::cout<<"Hello2";
return 9;
}
int a = 10;
bool dec = (a == hello() || a == world())
bool dec = (a == hello2() || a == hello() || a == world())
第一个语句的输出将是:
Hello
因为a == world()
将不会被执行,而第二个Hello2 Hello
将被执行,因为比较会一直持续到第一次成功。
对于&&
运算符,比较会一直发生,直到第一次失败(因为这足以确定整个语句的结果)。
答案 1 :(得分:1)
这可能取决于您设置的标志。二叉树搜索速度更快,但通常需要处理更多代码。所以,如果你针对尺寸进行优化,它可能不会。我不确定它是否会这样做。你知道,gcc根据很多标志进行了优化。 O1,O2,O3,O4只是表示大组标志的简单形式。您可以在此处找到所有优化标记的列表:http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
尝试在该页面中搜索字符串,二叉树等。
答案 2 :(得分:1)
几乎肯定不是。二进制搜索需要某种排序
关系,以及比较少于的关系的能力。编译器
不能假设这样存在,即使它找到了一个,它也不能
假设它定义了一个对应的等价关系
==
。也有可能编译器无法确定
定义排序关系的函数没有副作用。 (如果它
有副作用,或表达式中的任何操作有副作用
效果,编译器必须尊重短路行为
||
。)最后,即使编译器做了所有这些......如果我发生了什么
仔细选择比较顺序,以便最频繁
案件是第一个。这种“优化”甚至可能最终结束
是一种悲观情绪。
处理这个的“正确”是创建一个映射,映射 字符串指向函数(或多态函数对象, 如果涉及某个州)。
答案 3 :(得分:0)
测试此方法的最佳方法如下所示。
int a = 0;
int b = 0;
if(a == a || b++) {
...
}
cout << b;
b
变量的值最后应为0
。 b++
部分将不会被执行。这是预期的行为,但可能会有一些例外情况,具体取决于编译器及其优化设置。甚至像JavaScript
这样的脚本语言也是这样的。