例如:我有一个由 while 循环组成的函数(这个函数会检查素数)
function isprime(int number){
int i=2;
int max= (int) sqrt(number)+1;
while(i<max){
if(number%i==0){
return 0;
}
i++;
}
return 1;
}
我知道这对于测试素数来说是一个非常糟糕的算法,但无论如何我的问题更多地关注循环。目前,该函数的四分之一操作“只是”检查条件。对于较大的数字,这可能是一个非常大的数字。
(快速示例 1:如果“number”为 1009,则将检查 while 条件 30 次、索引 30 次操作、if 条件 29*2 次操作。即 118 次操作)
我意识到我可以在 while 条件下剪切和粘贴,并使索引通过最大值,同时导致额外的操作,不会伪造返回值。因此,如果我将所有内容从“if...”删除为“i++;”并粘贴三次(或n)次,检查while条件只占用1/10(或1/(1+3n)次操作,同时创建最多+2*3(或+(n-1 )*3) 不必要的操作。
(快速示例 2:如果“number”为 1009,则意味着检查 while 条件 11 次、索引 33 次操作、if 条件 33*2 次操作。即 100 次操作,少了 13 次)
由于我目前正在试验非常大的数字(用外行人的话来说:“条件将在非常非常非常长的时间内为假”),因此粘贴 if 条件和增量数千次将是有用的,但非常不切实际 -所以我的问题是:
是否有一个工具(或我缺少的技术)可以为我做到这一点,但保持代码清晰且易于修改?
提前致谢!
你的问题有点不清楚。
首先,你可以稍微改变你的算法;例如加 2,而不是加 1(因为每个大于 2 的素数都是奇数)。
然后,当被要求optimize(例如与g++ -Wall -O2
),编译器通常会做一些循环展开,就好像它多次“复制”(并不断折叠)循环体一样。
With GCC,您可以通过例如以下方式帮助优化器:使用__builtin_expect,例如和
#ifdef __GNUC__
#define MY_UNLIKELY(P) __builtin_expect((P),0)
#else
#define MY_UNLIKELY(P) (P)
#endif
然后你会编码
if(MY_UNLIKELY(number%i==0))
return 0;
最后,手动优化代码可能不值得,您应该进行基准测试。 (这CPU缓存今天非常重要,因此展开太多可能会减慢代码速度,另请参阅__builtin_prefetch
in GCC and this).
你也可以考虑元编程 and 多阶段编程设施;在像这样的语言中元奥卡姆 or 通用语言元编程手段多得多比 C++11template
事物。你可以考虑生成C代码在运行时(然后dlopening it),或者使用 JIT 编译库,例如libjit(例如,做部分评价)。另请阅读 J.Pitrat 的博客元组合搜索,以及维基页面eval. My MELT系统表明这些技术可以(痛苦地)与 C++ 相关使用(MELT 在运行时生成 C++ 代码,因此可以通过这种方式进行元编程)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)