如果最后一个条件为真,那么在以下程序中,我们必须检查之前的所有条件。 在下面的程序中是否有可能实现开关盒? 我将非常相似的代码转换为Arm组件。
main()
{
int x;
if (x< 32768)
x<<15;
elseif(x<49152)
(x<<12)- 7;
elseif(x<53248)
(x<<11)- 13;
elseif(x<59392)
(x<<10)-27;
elseif(x<60928)
(x<<9)-61;
elseif(x<62208)
(x<<8)-139;
elseif(x<64128)
(x<<7)-225;
elseif(x<65088)
(x<<6)-414;
elseif(x<65344)
(x<<5)-801;
elseif(x<65488)
(x<<4)-1595;
elseif(x<65512)
(x<<3)-2592;
elseif(x<65524)
(x<<2)-4589;
elseif(x<65534)
(x<<1)-8586;
}
希望有人能帮助我。
答案 0 :(得分:4)
您无法使用开关执行此操作,因为您需要使用常量值来与x进行比较,而不是布尔条件。但你可以使用这样的结构:
struct {
int u_limit;
int shift_left;
int add;
} ranges[13] = { {32768, 15, 0}, {49152, 12, -7} /*, ...*/};
for (int i = 0; i < 13; i++) {
if (x < ranges[i].u_limit) {
x = x << ranges[i].shift_left + ranges[i].add; break;
}
}
当然,你可以用二进制搜索替换线性搜索以获得一些加速。
答案 1 :(得分:4)
首先要做的事情是:你关注性能吗?如果是这样,您是否有实际分析数据显示此代码是热点,并且没有其他内容显示在配置文件中?
我对此表示怀疑。事实上,我愿意睡觉,你甚至没有对它进行基准测试。您正在查看代码并尝试对其进行微观优化。
如果是这种情况,那么答案很简单:停止这样做。以编写代码的方式编写代码,并专注于提高代码的算法效率。让编译器担心优化事情。如果性能证明不足那么配置文件并关注分析的结果。几乎总是能够解决您的性能问题:选择性能更佳的算法。答案几乎永远不会“修补if
声明”。
现在,回答你的问题:switch
在这种情况下无用,因为没有理智的方式来表示x < 32768
中的概念case
}语句,没有为x
的每个这样的值写一个语句。显然这是实际的,也不是理智的。
更重要的是,你似乎在错误的观念下运作,switch
会转化为更少的比较。在一些罕见的情况下,编译器可以避免比较,但大多数时候switch
将表示与case
语句一样多的比较。因此,如果您需要使用switch
针对10000个不同的可能值检查变量,您将获得10000次比较。
在您的情况下,您正在检查超过10,000个可能值的方式,因此简单的if
构造与“小于”运算符相结合更有意义,并且比{{{ {1}}。
你写了“如果最后一个条件为真,那么在跟随的程序中这就不必要了,我们必须检查它之前的所有条件。”是的,你做到了。您可以重写它,以便如果最后一个条件为真,您只需要进行两次比较。但是你只需要解决它的问题:如果switch
你最终必须检查所有其他可能的值,那么你就会回到你开始的地方。
一种可能的解决方案是执行二分查找。这肯定有资格作为算法改进,但是如果没有硬数据,这确实是一个热点,这将是一个相当愚蠢的练习。
最重要的是:编写正确易于理解且易于维护和改进的代码,并且不必担心重新排序x< 32768
语句。 perreal的出色答案显示了简单易懂和维护代码的一个很好的例子。
关于编写正确代码的主题,C和C ++中没有if
这样的东西。这让我们最后一点:在微优化代码之前至少尝试运行编译器。