有几篇文章比较了C++风格函数std::copy, std::equal, std::fill
和C风格函数std::memcpy, std::memcmp, std::memset
的性能,例如:
但是我还没有找到从实际的Angular 来证明这些新功能取代旧功能的理由。当然,功能列表并不详尽。
这些新版本的实际优势是什么?
如果性能不是选择的标准,那么用C++版本替换所有出现的这些C风格函数是否可取(时间允许的话)?
我试图理解为什么在c++
中引入了一些函数,以及是否有必要进行替换。
3条答案
按热度按时间wmomyfyw1#
正如在评论中指出的,
std::copy
等工作,而std::memcpy
等只在非常有限的情况下工作。特别是,std::memcpy
不适用于任何具有非平凡构造函数的东西,所以对于任何标准容器都不适用。即使在C风格struct
或struct
s的C风格数组上使用,它只做一个浅拷贝,所以根据对象的语义,它甚至可能在包含指针的C风格struct
上也不起作用。至于性能,当然没有什么是可以保证的,但是编译器可以访问
std::copy
的源代码。(因为它是一个模板),并且通常能够内联它-对于C风格的struct
s,这通常会导致复制更大的块(机器字,而不是字节)。在std::memcpy
的情况下,通常有一个函数调用,它隐藏了有关底层上下文的任何信息,需要一个字节拷贝(导致循环次数增加),或者处理对齐和可能的奇数字节的复杂逻辑。C标准确实允许memcpy
是一个宏,解析为一个特殊的符号,它会触发某种编译器优化,但我不认为这在C中是法律的。一些早期的、标准C之前的C编译器确实识别memcpy
,就好像它是一个关键字一样,但这都是很久以前的事了(在第一个C标准出现之前)。在今天的C代码中,绝对没有理由使用
std::memcpy
。9udxz4iz2#
memset
有两个严重的限制。首先是容器。对于使用连续内存的容器,只能
memset
多个元素。它可以用于std::array
或std::vector
,但不适用于大多数其他容器。接下来是元素。你只能复制
memset
这样的普通对象。像std::string
这样“简单”的东西已经不能复制了。memset
可以在某些情况下使用。你提到的其他函数更普遍适用,当它们可以被memset
替换时,编译器可以做到这一点。vkc1a9a23#
但我还没有找到从实际Angular 来看这些新功能取代旧功能的理由。
这些函数更通用。
memcpy
和memset
仅定义为 * TriviallyCopable * 类型的连续范围,而memcmp
(通常)仅对没有填充的 * TriviallyCopable * 类型的连续范围有意义。注意:单个对象是长度为1的连续范围。只有当它们做同样的事情时,性能才具有可比性,并且根据as-if规则,当可以证明范围不重叠时,实现可以选择以与
memcpy
完全相同的方式实现对std::copy
的调用,否则可以选择memmove
。类似地,std::fill
与memset
以及std::equal
与memcmp
1。1.稍微修改了一下,因为它不关心更小或更大,只是相等