我有很多字符串,每个字符串大小不超过8个。
我需要使用memcmp()
/ strcmp()
进行大量比较。
我想知道如果将所有比较转换为std::uint64_t
,比较是否会更快。在这种情况下,至少理论上的比较将是无分支的,也会在单CPU操作中发生。
有没有人尝试过类似的东西?
以下是生成这些数字的一些测试代码。我假设小端机器。
如果我使用htobe32()
/ htobe64()
,我知道代码可以大大简化。
#include <cstdint>
#include <algorithm> // std::reverse_copy
namespace rev_impl{
template<typename T>
T rev(const char *s){
T t;
char *pt = reinterpret_cast<char *>(&t);
std::reverse_copy(s, s + sizeof(T), pt);
return t;
}
}
inline uint32_t rev32(const char *s){
return rev_impl::rev<uint32_t>(s);
}
inline uint64_t rev64(const char *s){
return rev_impl::rev<uint64_t>(s);
}
#include <iostream>
#include <iomanip>
template<typename T>
void print_rev(const char *s){
constexpr auto w = sizeof(T) * 2;
std::cout << std::setw(w) << std::setfill('.') << std::hex << rev_impl::rev<T>(s) << '\n';
}
inline void print_rev32(const char *s){
return print_rev<uint32_t>(s);
}
inline void print_rev64(const char *s){
return print_rev<uint64_t>(s);
}
int main(){
print_rev64("\0\0\0\0\0\0\0a");
print_rev64("a\0\0\0\0\0\0\0");
print_rev32("Niki");
print_rev32("Nika");
print_rev32("Nikz");
}
这是测试输出:
..............61
6100000000000000
4e696b69
4e696b61
4e696b7a
答案 0 :(得分:0)
如果您只需要转换字符串文字,可以编写rev
以接受char
的数组,如下所示
template <typename T, std::size_t N,
typename = typename std::enable_if<(N<=sizeof(T)+1U)>::type>
constexpr T rev (char const (&arr)[N])
{
T ret = 0;
std::size_t ui = -1;
while ( ++ui < N-1U )
ret <<= CHAR_BIT, ret |= arr[ui];
while ( ++ui < sizeof(T) )
ret <<= CHAR_BIT;
return ret;
}
请注意,从C ++ 14开始,可以定义此函数constexpr
,因此您可以编写一些内容
constexpr auto fb = rev<std::uint64_t>("foobar");
以下是您重写的代码以使用字符串文字
#include <cstdint>
#include <climits>
#include <iostream>
#include <iomanip>
#include <type_traits>
namespace rev_impl
{
template <typename T, std::size_t N,
typename = typename std::enable_if<(N<=sizeof(T)+1U)>::type>
T rev (char const (&arr)[N])
{
T ret = 0;
std::size_t ui = -1;
while ( ++ui < N-1U )
ret <<= CHAR_BIT, ret |= arr[ui];
while ( ++ui < sizeof(T) )
ret <<= CHAR_BIT;
return ret;
}
}
template <typename T, std::size_t N>
inline uint32_t rev32 (char const (&s)[N])
{ return rev_impl::rev<uint32_t>(s); }
template <typename T, std::size_t N>
inline uint64_t rev64 (char const (&s)[N])
{ return rev_impl::rev<uint64_t>(s); }
template<typename T, std::size_t N>
void print_rev (char const (&s)[N])
{
constexpr auto w = sizeof(T) * 2;
std::cout << std::setw(w) << std::setfill('.') << std::hex
<< rev_impl::rev<T>(s) << '\n';
}
template <std::size_t N>
inline void print_rev32 (char const (&s)[N])
{ return print_rev<uint32_t>(s); }
template <std::size_t N>
inline void print_rev64 (char const (&s)[N])
{ return print_rev<uint64_t>(s); }
int main ()
{
print_rev64("\0\0\0\0\0\0\0a");
print_rev64("a\0\0\0\0\0\0\0");
print_rev32("Niki");
print_rev32("Nika");
print_rev32("Nikz");
}