【发布时间】:2016-08-26 22:01:48
【问题描述】:
最近的code golfing post 询问了以下在 C 中快速实现的可能性(假设n 是一个无符号整数):
if (n==6 || n==8 || n==10 || n==12 || n==14 || n==16 || n==18 || n==20)
一种可能的简化方法是观察数字a[]={6,8,10,12,14,16,18,20} 形成一个arithmetic progression,因此移动范围,然后使用一些bitwise tricks
if (((n - 6) & 14) + 6 == n)
导致实现更短(并且可能确实更有效),如 John Bollinger 的answered。
现在我要问的是什么是类似优雅(并且希望同样有效)的实现
if (n==3 || n==5 || n==11 || n==29 || n==83 || n==245 || n==731 || n==2189)
提示:这一次数字a[k] 形成一个几何级数:a[k]=2+3^k。
我想在一般情况下,最好的办法是对数字 a[k] 进行排序,然后进行对数搜索以测试 n 是否是排序数组的成员。
【问题讨论】:
-
如果这是一个时间超过空间的权衡,那么我将分配一个 2189 字的缓冲区,除了特定的位置(3、5、11 等)之外,用零填充,然后简单地执行数组查找(这是非常快的,因为它是硬件实现的)。这不是很优雅,但会以空间性能为代价为您提供最佳时间性能。
-
这样的问题不应该发到codereview.stackexchange.com吗?
-
FWIW,
((n - 6) & 14) + 6 == n可以简化为(n - 6) | 14 == 14。 -
@UriBrecher - 对于 2k 值,也许。对于一般情况,巨大的查找表对缓存的影响可能不可忽略。
-
您是追求原始速度还是外观优雅的 C 代码?它们很可能是不同的。除法(包括模)运算是现代处理器上最慢的运算,因此 thiru 的答案看起来很酷,但可能不会比一系列比较快。如果您确实关心速度,请在做出决定之前检查编译器的输出和 benchmark。还要考虑分支在紧密循环中很慢。如果您的优化器不够智能,无法自动执行此替换(Clang 是,其他不是),请考虑使用按位 OR 而不是逻辑 OR。
标签: c++ c performance sorting search