如何在C++中比较短字符串(最多 8 个字符)
How to compare short strings(maximum 8 chars) in C++
我想用它来比较性能关键代码中的短字符串(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 标准),
char
或unsigned char
类型。
可靠、最便携的方法就是简单地使用 strcmp()
.
你不能可靠地(见下面的评论)将一串字符"投射"到这样的整数中。 您需要使用按位运算符,如下所示:
在 C++ 中使用按位运算符将 4 个字符更改为 int
(当然,您只能将四个字符放入一个 32 位整数中。
但是我不确定为什么你假设像这样"原子化"字符串会比仅仅调用strcmp()更快,strcmp()在大多数C库中的汇编代码中实现。
尝试双向运行代码并查看。您可能会发现它们以相同的速度运行!这种测试通常内存带宽有限,因此循环中执行的指令数量几乎无关紧要。
请务必注意,仅当字符串值已用 null 填充到整数大小时,这才有效,您将其声明为对不同答案的注释。
至于它是否合法C++,请参阅允许将"T*"与"char*"混叠。反过来也允许吗?
- 最多获取2个对象
- 在另一个类视图中添加最多2个图表的正确方法是什么
- 计算 PI 最多 42 位小数
- 删除/替换C++字符串中的多字符 (ÿû)
- 最多总和为'k'的子序列
- 从组件的 std::type_index 获取派生最多的类型
- 如何在C++中找到变量派生最多的子类?
- 初始化一个由 p 指向的新 INTSTK,它最多可以存储 m 个
- 最多匹配n个字符
- 舍入 QDecDouble 值,精度最多为两个字符
- 查找单个字符串中重复次数最多和次数第二多的字符
- C++最多读取一个字符或另一个字符
- C++ 如何从标准输入加载到最多 5 个字母数字字符的字符数组
- 如何在C++中比较短字符串(最多 8 个字符)
- 如何逐行枚举从文件中读取的文本,并找到 C 中字符和单词最多的行
- C++比较最多 "%" 个字符的字符串
- c++对一个数字进行除法处理,每次掷骰子最多显示60个字符
- 从最多X个字符开始构造std::string,止于null char
- C++返回字符串中最常见字符的函数中的错误.多字节字符
- Istream最多使用N个空白字符