快速提问。例如,使用一些大约1000个选项的大型案例:哪种是“最佳”方法?我并不是特意想要直接获得更快的结果。
switch (foo) {
case 0:
// code ...
break;
// One, two, skip a few...
case 1000:
// code ...
}
或分裂可能结果的东西,以便它可以快速找到正确的案例陈述。类似的也是:
if (foo < 101) {
if (foo < 51)
switch (foo) {}
else
switch (foo) {}
} else if (foo > 100 && foo < 201) {
// skipped for convenience
} else if (foo > 900) {
if (foo < 951)
switch (foo) {}
else
switch (foo) {}
}
我想第二种方法对于较大的数字要快得多,但第一种方法似乎也可以轻松通过它,因为它不是经常检查语句。这些方法中有一种不赞成还是有更好的方法?这是针对C的,但我有兴趣知道它与其他语言的一致性。谢谢!
答案 0 :(得分:9)
switch
语句可以非常快,但这只能在cases
的特殊序列上实现,并且可能不实际,它实际上取决于可能cases
-fno-jump-tables
1}}。编译器可能会也可能不会使用跳转表,我确实发现这个http://blog.jauu.net/2010/06/15/GCC-generated-Switch-Jump-Tables/很有意思。
JUMP表格可以非常快,因为它只计算偏移量并跳转到适当的地址。
GCC确实有fun_table[indice]();
,它会完全禁用它。
有时你可以使用函数指针数组和特殊索引来构建自己的跳转表,这可以使你的代码非常快,但在所有情况下都不实用,想象你有一个开关,在每种情况下你都会调用一个函数,你可以构建一个函数指针数组,设置一个默认函数只是为了安全,然后你只需要{{1}}而不是一个开关我为自己的虚拟机做了一次。
答案 1 :(得分:1)
我认为switch语句通常被解释为底层汇编语言中的goto,这将使第一种方法显着加快。
这似乎支持这一点,虽然它不完全证明:http://en.wikibooks.org/wiki/Optimizing_C%2B%2B/Writing_efficient_code/Performance_improving_features#Case_values_of_switch_statements
答案 2 :(得分:1)
我认为switch语句更好,至少从代码可读性的角度来看(并且可能从速度的角度来看,因为它只选择一个块来运行,因为它必须评估多个条件,如第二个例子中所示)。 )
答案 3 :(得分:1)
不推荐任何功能应该适用于大约1.5个屏幕,因此这样一个巨大的开关声明将不适合这个账单。为了解决这个问题,有一个dispatch表。你要做的就是索引数组以找到适当的函数来调用。
答案 4 :(得分:0)
我发布此内容仅供参考,因为samy.vilar已经为函数数组提供了最优雅的解决方案。如果您使用GCC,它可以理解案例范围。此代码最终将以与第二种解决方案非常相似的方式运行,从而产生一些二叉树代码路径(假设没有编译器优化)。
int nested_switch(int i)
{
switch (i) {
/* i is in the 1..10 range */
case 1 .. 10:
switch (i) {
/* i is in the 0..5 range */
case 1 .. 5:
switch (i) {
case 1:
break;
case 2:
break;
...
case 5:
break;
}
case 5 .. 10:
switch (i) {
case 6:
break;
case 7:
break;
...
case 10:
break;
}
}
/* i is in the 11..20 range */
case 11 .. 20:
switch (i) {
...
}
}
return 0;
}