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

How to compare short strings(maximum 8 chars) in C++

本文关键字:最多 字符 字符串 C++ 比较      更新时间:2023-10-16

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

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

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

您还有其他建议可以非常快速地做到这一点吗?

此代码将产生不正确的行为,因为 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()比较字符串。它已经非常快了,并且会给出正确的结果。

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

来自标准:第 3.10.10 节

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

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

可靠、最便携的方法就是简单地使用 strcmp() .

你不能可靠地(见下面的评论)将一串字符"投射"到这样的整数中。 您需要使用按位运算符,如下所示:

在 C++ 中使用按位运算符将 4 个字符更改为 int

(当然,您只能将四个字符放入一个 32 位整数中。

但是我不确定为什么你假设像这样"原子化"字符串会比仅仅调用strcmp()更快,strcmp()在大多数C库中的汇编代码中实现。

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

请务必注意,仅当字符串值已用 null 填充到整数大小时,这才有效,您将其声明为对不同答案的注释。

至于它是否合法C++,请参阅允许将"T*"与"char*"混叠。反过来也允许吗?