我正在尝试编写一个非常便宜的 C++ 代码片段来对以 null 结尾的短字符串执行以下操作。
输入是一个字符串,如"ABC"
。它以 null 终止,最大长度为 4(或 5,带有 null 终止符)。
输出到 char[4]
,它不是空终止的,应该在右边用空格填充。所以在这种情况下,它将是 {'A','B','C',' '}
可以假设输入字符串正确地以 null 结尾,因此无需读取输入的第二个单词来确定。 4 个字节是最长的。
所以它周围的代码看起来像这样:
char* input = "AB";
char output[4];
// code snippet goes here
// afterward output will be populated with {'A','B',' ',' '}
这能以多低的成本完成? 如果重要:我正在与:
Linux 2.6.32-358.11.1.el6.x86_64 #1 SMP x86_64 x86_64 x86_64 GNU/Linux
最后,输入是词对齐的。
最佳答案
这样的事情怎么样:
typedef unsigned int word;
int spacePad(word input) {
static const word spaces = 0x20202020;
word mask =
!input ? 0 :
!(input & 0x00ffffff) ? 0xff:
!(input & 0x0000ffff) ? 0xffff :
!(input & 0x0000ff) ? 0xffffff :
0xffffffff;
// or without branches
word branchless_mask =
1u << (8 * (
bool(input & 0xff000000) +
bool(input & 0x00ff0000) +
bool(input & 0x0000ff00) +
bool(input & 0x000000ff)
));
return (spaces & mask) | (input & ~mask);
}
如果我没有搞砸,spacePad(0xaabb0000)
就是 0xaabb2020
。
您可以使用 SSE 内部函数代替计算和掩码,这可能会更快,因为您可以在几条指令中获得掩码,然后掩码移动将完成剩下的工作,但编译器可能会移动您的变量从 SSE 到标准寄存器,这可能会超过轻微的 yield 。这完全取决于您需要处理的数据量、数据在内存中的打包方式等。
如果输入是 char*
而不是 int
,通常需要额外的代码,因为转换可以读入未分配的内存。但是,由于您提到所有字符串都是字对齐的,因此强制转换就足够了,实际上即使有一些未分配的字节,它们也与至少一个分配的字节位于同一个字上。由于您只是在阅读,因此没有内存损坏的风险,而且在我所知道的所有体系结构上,硬件内存保护的粒度大于一个字。例如,在 x86 上,内存页通常是 4k 对齐的。
现在这一切都很好,但是:在选择一个解决方案之前,对其进行基准测试,这是知道哪个最适合您的唯一方法(当然除了编写代码的温暖模糊感觉这个^^)
关于c++ - 单个单词的快速填充 strcpy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20224544/