比较以下两个表达式
哪个更好?
std::bitset<8>(5).count()
__builtin_popcount(5)
哪个更好?
int __builtin_popcount(unsigned int);
__builtin_popcount
是GCC内置函数,而 std::bitset<N>::count
则是C++的标准函数。
这两个函数的作用相同:返回被设为 true
的位数。
你应该使用哪一个函数?
尽量使用C++标准函数,因为其他编译器不支持 __builtin_popcount
函数。
更新
如果你查看Google基准测试工具所做的统计数据:
#include <bitset>
static void GccBuiltInPopCount(benchmark::State& state) {
for (auto _ : state) {
__builtin_popcount(5);
}
}
BENCHMARK(GccBuiltInPopCount);
static void StdBitsetCount(benchmark::State& state) {
for (auto _ : state) {
std::bitset<8>(5).count();
}
}
BENCHMARK(StdBitsetCount);
使用GCC 9.2和标志-std=c++2a -O3
,GCC内置函数比std::bitset<N>::count()
函数慢10%,但由于两个函数的ASM输出相同,基准测试中的差异可能是由其他因素引起的。
-02
产生相同的汇编输出,但 -03
不会。 - NutCracker-O3
,仍然是一样的结果。也许在代码中不使用返回值对优化有些影响?我可以想象,在第二个示例中,由于该值根本没有被使用,因此对__popcountdi2
的汇编器调用可能会被丢弃。 - Aconcaguastd::bitset<N>::count()
。 - NutCracker当你不知道 std::bitset<N>::count
中 N 的值时,我认为第二个更好。
更新: 你可以尝试使用 std::popcount。
std::bitset
保证可移植性和行为一致性。 - Tas