赋值运算符-每个成员或二进制副本
Assignment operator - per member or binary copy?
我想知道,只要所有包含的赋值除了将二进制值传输到地址之外没有任何副作用,那么只将字节从源对象指针复制到目标,而不是将每个目标成员分配给每个源成员,这不是更有效吗?
作为一个子问题。。。我想知道读取模式是如何影响内存控制器负载的。显然,当MC从正确对齐的地址读取其全宽时,它是最有效的。也许将所有成员合并为用于对齐的最大宽数据类型序列会更有效,例如,如果MC是64位,成员数据集是10个字节,则复制64位和16位的值,即使成员是10个char
,因此这种复制方式将比一次复制每个成员字符更好地使MC饱和。
只要只需要字节复制,就让编译器为您生成默认的
它也会自动优化它,如果最有效的话,使用memcpy
。
额外的好处是,如果您添加了一个具有更复杂(自包含)语义的成员,编译器仍然会做正确的事情。
如果您添加了一个在语义上不复制其数据的成员,那么您只需要自己进去完成即可。
一般来说,memcpy总是比每个成员拷贝快。一些注意事项:
-
memcpy的工作方式通常是尽可能进行对齐的读/写。然而,这是一个完全依赖于平台的事情,理论上memcpy可能是效率非常低的
-
如果结构未对齐,则每个成员副本也需要未对齐的访问
-
压缩结构将更慢,除非它们也对齐(如SSE、NEON等)
-
如果结构中有填充,memcpy将不可避免地复制比所需更多的字节。
-
确定答案的最佳方法是在目标机器上构建并运行/配置它,记住不同的结构可能具有不同的特性。
memcpy仅适用于POD类型。一旦有了析构函数、构造函数、虚拟函数、私有数据、继承、内存,对象就会有未定义的行为。所以,它适用于这样的类
class PODType {
public:
int x;
int y;
};
class Object {
public:
PODType m;
Object& operator=(Object const& x) {
memcpy(&m, x.m, sizeof(PODType));
return *this;
}
};
但现在,随着程序的发展,有人会更改PODType以拥有一个自定义构造函数,因为这很方便,或者添加一个析构函数,或者做一些其他事情使其成为非POD。现在,所有与它关联的类都将具有未定义的行为。在这些情况下,最好使用编译器生成的赋值运算符。
如果你担心性能,
- 不要过早进行优化
- 使用探查器和度量
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 有根的二进制搜索树.保留与其父级的链接
- 多态二进制函数
- 正在读取二进制文件(is_open)
- visual在c++中将十进制数转换为二进制数
- C++十进制到二进制,如何转换
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- 二进制搜索树叶数问题
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 为什么二进制搜索在我的测试中不起作用
- 重载==不适用于二进制树
- 正在尝试重载二进制搜索树分配运算符
- 在C++中将类(带有Vector成员)保存为二进制文件
- 用callgrind追踪不必要的副本
- 如何从二进制文件中读取字符串
- C++文件二进制模式副本
- 具有标准C++的大型二进制文件副本
- 为二进制搜索树副本构造函数编写辅助函数
- 赋值运算符-每个成员或二进制副本
- Cmake,.lib,dll并避免二进制中的多个.lib副本