如何比较C ++中的短字符串(最多8个字符)

时间:2014-12-22 21:48:12

标签: c++

我想用它来比较性能关键代码中的短字符串(4到8个字符长)。我想将它们转换为整数值并比较这些值而不是比较字符串:

const char* str = "abcdefgh";
uint64_t num = *reinterpret_cast<const uint64_t*>(str);

在不检查str指针的对齐情况下,将uint64_t强制转换为char*是否安全?我只在ARM和Intel CPU上使用该代码,32位和64位。 如果行为定义良好且强制转换是安全的,那么当指针未对齐到8个字节时,我是否应该期待性能下降?

您是否有其他建议以非常快的方式执行此操作?

4 个答案:

答案 0 :(得分:2)

此代码将产生不正确的行为,因为null终止符后面的字节内容不是字符串的一部分。例如,考虑字符串:

char str1[8] = { 't', 'e', 's', 't', 0, 0, 0, 1 };
char str2[8] = { 't', 'e', 's', 't', 0, 0, 0, 2 };

两个字符串都具有值"test",但将它们作为整数进行比较会说它们是不同的,因为字符串末尾后面的一个字节是不同的。此外,如果字符串从分配的内存页的末尾开始少于8个字节,则尝试从中读取整数将导致段错误。

使用strcmp()来比较字符串。它已经非常快,并且会给出正确的结果。

答案 1 :(得分:1)

您提议的内容不可移植,实际上违反了C ++严格别名规则。这是未定义的行为。

来自标准:第3.10.10节

  

如果某个程序试图通过以下某种类型之外的 glvalue 访问对象的存储值,则行为未定义:

     
      
  • 对象的动态类型,
  •   
  • 对象的动态类型的cv限定版本,
  •   
  • 与对象的动态类型相似的类型(如4.4中所定义)
  •   
  • 与对象的动态类型对应的有符号或无符号类型的类型
  •   
  • 与对象的动态类型的cv限定版本对应的有符号或无符号类型的类型,
  •   
  • 聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(递归地,包括子聚合或包含联合的元素或非静态数据成员),
  •   
  • 一种类型,它是对象动态类型的(可能是cv限定的)基类类型,
  •   
  • charunsigned char类型。
  •   

最可靠,最便携的方法就是使用strcmp()

答案 2 :(得分:0)

你可以可靠地(见下面的评论)&#34; cast&#34;一串字符到这样的整数。您需要使用按位运算符,如下所示:

Using bitwise operators in C++ to change 4 chars to int

(当然,你只能将四个字符组合成一个32位整数。)

但我不确定你为什么要假设&#34;雾化&#34;像这样的字符串将比调用strcmp()更快,strcmp()在大多数C库的汇编代码中实现。

答案 3 :(得分:0)

尝试双向运行代码并查看。您可能会发现它们以相同的速度运行!这种测试通常是内存带宽有限的,因此循环中执行的指令数量几乎不重要。

重要的是要注意,这只有在字符串值填充了整数大小的空值时才有效,您将其表示为对不同答案的注释。

至于它是否是合法的C ++,请参阅Aliasing `T*` with `char*` is allowed. Is it also allowed the other way around?