我读过一些相关的问题,但没有关于memcpy
和strncpy
之间的速度比较。
您建议如何跟踪关键部分中的字符串内容?
- 避免动态内存分配
- 代码的优雅和可读/可理解(代码行很少)
- 快速处理(指令少,防止分支遗漏)
- 能够通过编译器进行优化(或已经使用优化指令实现)
我在考虑 c 函数:
-
memcpy
需要计算最小长度(请参阅 coliru.stacked-crooked.com 上的代码片段)void copy (char dst[20], const std::string& src) { if (src.size() < sizeof(dst)) { memcpy (dst, src.c_str(), src.size()+1); } else { memcpy (dst, src.data(), sizeof(dst)-1); dst[sizeof(dst)-1] = 0; } }
-
strncpy
搜索终止空字节,不必要的搜索填充所有最终字节(请参阅代码片段)void copy (const std::string src, char (*dst)[20]) { strncpy (dst, src.c_str(), sizeof(dst)-1); dst[sizeof(dst)-1] = 0; }
-
snprintf
? -
std::string::copy
正如 DYP 的评论所暗示的那样... -
std::copy
正如同一个 DYP 的评论再次暗示的那样...... -
还有其他想法吗?
可以执行基准测试,但它应该基于多个编译器/版本、不同的标志集和不同的硬件/操作系统。我更喜欢根据您的反馈/背景/专业知识或数学知识给出答案......
由于这是一个一般性问题,搜索相同相关问题的人将欣赏一个一般性的答案,而不是我自己当前的具体情况。
供您参考,一个线程需要在文件中写入一些std::string
,使其内容可以被另一个线程更改。我无法更改另一个线程,并且另一个线程非常繁忙。如果我不锁定(互斥锁/旋转锁)字符串副本,我有时会遇到一些问题。因此,我想快速复制这些std::string
并将它们写在锁定部分之后。
首先,我无法判断哪个版本更快。正如您可能知道的那样,这在很大程度上取决于您的编译器、系统、实现等。
如果您提前知道大小(您有一个std::string
并且size()
需要O(1)
),那么使用memcpy
可能会更快,因为它要做的事情更少(只是副本,没有比较)。你可以这样写:
void copy(char* buffer, std::size_t buffersize, const std::string& str)
{
std::size_t len = std::min(buffersize-1, str.size());
memcpy(buffer, &str[0], len); // using &str[0] instead of data()
buffer[len] = ' ';
}
但我不会接受任何人的话。正确的做法是测试您拥有的所有变体并决定您的特定场景(我对此一无所知)。
我的具体情况是在关键部分(旋转锁定)中快速存储一些
std::string
,然后转储这些字符串。因此,我想阻止动态内存分配。
我不明白的是为什么不使用std::string
.如果要阻止分配,可以为字符串reserve()
一些内存(与 char 数组上的内存量相同)。或者,您可以获取对字符串的 const 引用并将其用于关键部分。不会进行分配。
当你使用 c_str() 而不是 data() 时,你可能会因为 std::string 创建一个临时副本来附加终止的 0。当你使用 data() 时,你不能使用 stncpy。
不知道是否有很多实现实际上执行该临时复制。 为终结者浪费一个字节似乎没什么大不了的。但:
- 在纯C++代码中,你永远不需要 c_str(),那么为什么要优化它呢?
- 这不仅浪费了一个字节,还需要时间来维护它
- 某些实现避免为非常短的字符串分配额外的动态内存。 在那里,能够存储一个字节或多或少很重要。
- 也许实现对子字符串操作进行了写入时复制优化?