c++ std::copy,std::equal,std::fill相对于memcpy,memset,memcmp的实际优势

d8tt03nd  于 11个月前  发布在  其他
关注(0)|答案(3)|浏览(140)

有几篇文章比较了C++风格函数std::copy, std::equal, std::fill和C风格函数std::memcpy, std::memcmp, std::memset的性能,例如:

但是我还没有找到从实际的Angular 来证明这些新功能取代旧功能的理由。当然,功能列表并不详尽。
这些新版本的实际优势是什么?
如果性能不是选择的标准,那么用C++版本替换所有出现的这些C风格函数是否可取(时间允许的话)?
我试图理解为什么在c++中引入了一些函数,以及是否有必要进行替换。

wmomyfyw

wmomyfyw1#

正如在评论中指出的,std::copy等工作,而std::memcpy等只在非常有限的情况下工作。特别是,std::memcpy不适用于任何具有非平凡构造函数的东西,所以对于任何标准容器都不适用。即使在C风格structstruct s的C风格数组上使用,它只做一个浅拷贝,所以根据对象的语义,它甚至可能在包含指针的C风格struct上也不起作用。
至于性能,当然没有什么是可以保证的,但是编译器可以访问std::copy的源代码。(因为它是一个模板),并且通常能够内联它-对于C风格的struct s,这通常会导致复制更大的块(机器字,而不是字节)。在std::memcpy的情况下,通常有一个函数调用,它隐藏了有关底层上下文的任何信息,需要一个字节拷贝(导致循环次数增加),或者处理对齐和可能的奇数字节的复杂逻辑。C标准确实允许memcpy是一个宏,解析为一个特殊的符号,它会触发某种编译器优化,但我不认为这在C中是法律的。一些早期的、标准C之前的C编译器确实识别memcpy,就好像它是一个关键字一样,但这都是很久以前的事了(在第一个C标准出现之前)。
在今天的C
代码中,绝对没有理由使用std::memcpy

9udxz4iz

9udxz4iz2#

memset有两个严重的限制。
首先是容器。对于使用连续内存的容器,只能memset多个元素。它可以用于std::arraystd::vector,但不适用于大多数其他容器。
接下来是元素。你只能复制memset这样的普通对象。像std::string这样“简单”的东西已经不能复制了。
memset可以在某些情况下使用。你提到的其他函数更普遍适用,当它们可以被memset替换时,编译器可以做到这一点。

vkc1a9a2

vkc1a9a23#

但我还没有找到从实际Angular 来看这些新功能取代旧功能的理由。
这些函数更通用。memcpymemset仅定义为 * TriviallyCopable * 类型的连续范围,而memcmp(通常)仅对没有填充的 * TriviallyCopable * 类型的连续范围有意义。注意:单个对象是长度为1的连续范围。
只有当它们做同样的事情时,性能才具有可比性,并且根据as-if规则,当可以证明范围不重叠时,实现可以选择以与memcpy完全相同的方式实现对std::copy的调用,否则可以选择memmove。类似地,std::fillmemset以及std::equalmemcmp 1。
1.稍微修改了一下,因为它不关心更小或更大,只是相等

相关问题