是否有哈斯克尔';在C预处理器宏中的s`let`/`in`?
我有一个如下的函数(用于素数seve,以防你好奇) 我已经将其重构到宏中是否有哈斯克尔';在C预处理器宏中的s`let`/`in`?,c,c-preprocessor,C,C Preprocessor,我有一个如下的函数(用于素数seve,以防你好奇) 我已经将其重构到宏中 #define PRIME_AT(index) (index * 3 + (index % 2 ? 2 : 1)) 出于性能和可读性的原因 我想知道是否有任何方法可以对该函数执行相同的操作: unsigned long long indexOf(unsigned long long prime) { int mod = prime % 6; return prime / 3 - (mod == 0 ||
#define PRIME_AT(index) (index * 3 + (index % 2 ? 2 : 1))
出于性能和可读性的原因
我想知道是否有任何方法可以对该函数执行相同的操作:
unsigned long long indexOf(unsigned long long prime) {
int mod = prime % 6;
return prime / 3 - (mod == 0 || mod == 3 || mod == 4);
}
无需重新计算prime%6
3次,如下所示
#define INDEX_OF(prime) (prime / 3 - ((prime % 6) == 0 || (prime % 6) == 3 || (prime % 6) == 4));
(这段代码将运行几十亿次,甚至几万亿次,因此性能至关重要)它不是标准的,但GCC(以及所有其他模拟它的编译器,即除了MSVC之外的所有编译器)支持一种称为“语句表达式”的东西。结合可能的
类型
,它可以使宏非常强大
#define MAX(a, b) ({ __typeof__((a)) __a = (a); typeof((b)) __b = (b); __a > __b ? __a : __b; })
({})
块中的最后一条语句必须是表达式语句,它将用作语句表达式的值
这就是说,如果a
和b
没有副作用,那么即使没有副作用,GCC也能很好地优化重复计算。不能简单地
#define INDEX_OF(prime,mod) (prime / 3 - (mod == 0 || mod == 3 || mod == 4));
真不敢相信我居然错过了,这么简单优雅的解决方案!事实上,如果您添加第二个宏,它将变得更加优雅,该宏的索引仅为((prime),(prime%6))请不要这样做。宏和函数之间没有性能差异(请检查两者的程序集列表)。编译器足够聪明,可以为您进行这样的微优化。但是如果你曾经写过,例如,(myPrimeNumber+1)的索引,你会感到惊讶。
#define INDEX_OF(prime,mod) (prime / 3 - (mod == 0 || mod == 3 || mod == 4));