c++ - 单个单词的快速填充 strcpy

标签 c++ c word memcpy strcpy

我正在尝试编写一个非常便宜的 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/

相关文章:

c - 了解 Linux 内核调度程序

mysql - 从 C 语言将 16 位整数数组插入 MySQL

mysql - 计算表列中的单词出现次数

c++ - 当代码中不存在代码行时,如何解决 Visual Studio 2010 C++ 中的错误 C2719

c++ - 反对使用 size_t 的理由是什么?

C++ UDP recvfrom 行为异常,WSAGetLastError = 10014

C++单词解密器

c++ - 带 std::index_sequence 的三元运算符

c - #define ISR(x) #pragma isr=x

python - 使用 Python 在句子中反转单词?