自定义类中的移动与复制性能
Move vs copy performance in custom classes
如果该类的成员主要是基本类型(如int等),那么与复制ctor相比,通过移动ctor创建类的实例如何(如果有的话)提高性能。 这些成员不是像复制CTOR中那样复制的吗?那么,在处理自定义类时,移动何时提供更好的性能呢?
如何(如果有的话)通过移动 ctor 创建类的实例 提高性能,与复制 CTOR 相比,如果成员说 类主要是基本类型,如 int 等,这些成员不就是 像在复制 CTOR 中一样复制?
在所有成员变量都是按值/POD 的情况下,根本不应该有任何区别。
因此,何时移动提供更好的性能,在处理 自定义类?
移动构造函数仅在新构造的对象可以从现有对象中"窃取"资源的情况下提供优势。
例如,假设您有一个临时std::string
,其中包含小说"战争与和平"的全部内容 - 所有1440页。
在经典的复制构造函数情况下,如果要将该临时字符串分配给非临时std::string
(例如成员变量或全局变量或其他任何内容),程序必须执行以下步骤:
- 释放目标
std::string
可能持有的任何先前缓冲区 - 分配一个长度为 (1440*chars_per_page) 字节的新缓冲区,供目标
std::string
保存 - 将所有 1440 页数据从临时
std::string
的缓冲区复制到目标std::string
缓冲区 删除临时字符串 - 的缓冲区(当临时字符串超出范围时)
如您所见,这将效率低下,因为我们复制了大量数据,即使我们实际上从未需要数据的第二个副本。 但是,由于我们有一个为std::string
实现的移动构造函数,因此C++11程序可以更智能,只需这样做:
- 释放目标
std::string
可能持有的任何先前缓冲区 - 将巨大的缓冲区从临时
std::string
传输到目标std::string
(请注意,我们所做的只是将源字符串的缓冲区值的指针复制到目标字符串;特别是我们不需要复制,甚至不需要读取任何实际的 1440 页数据! - 将临时字符串指向缓冲区的指针值设置为 NULL(这样它就不会尝试释放它或稍后使用它)
。仅此而已;我们不必分配第二个大缓冲区,然后复制大量数据,只需滑动几个指针值即可实现所需的最终状态。 这是一个很大的性能胜利,我们可以侥幸逃脱,因为我们知道临时字符串无论如何都会被删除,所以"窃取"它持有的内部数据没有害处。
我不知道std::string
是否算作"自定义类",但是只要您有一个动态分配内部状态的类,您就可以在自己的类中使用相同的技术。
与复制 ctor 相比,通过移动 ctor 创建类的实例如何(如果有的话)提高性能,如果该类的成员主要是基本类型,如 int 等。
其实不然。
这些成员不是像复制 ctor 中那样复制的吗?
是的。
那么,在处理自定义类时,移动何时提供更好的性能呢?
当你有"间接"资源时,比如指针引用的数据,这样你就可以"交换"指针,甚至避免接触它们指向的东西。(这就像把一辆大篷车从你的车上解开,然后重新挂在另一辆车上。就是这样。
如果类仅包含无论如何都必须复制的数据,则使类可移动没有任何好处。(这就像试图将大篷车的内容"移动"到另一辆大篷车上:你别无选择,只能实际进入,捡起所有东西并用手转移。
与复制 ctor 相比,通过移动 ctor 创建类的实例如何(如果有的话)提高性能
你误会了。通常,您不会选择对象是使用移动 ctor 还是复制 ctor 构造 - 它隐含在其定义的上下文中。所以没有太多的选择。当然,如果移动 ctor 不可用,则复制构造是后备。不过,不要把它当作一种选择。
如果所述类的成员主要是基本类型,如 int 等,这些成员不是像复制 CTOR 中那样复制吗?
它们可能根本不会被复制,即编译器可能完全省略对象的构造,只使用你传递的对象。但是,如果构造确实发生,那么是的,int
s等将被复制(假设默认移动ctor)。
那么,在处理自定义类时,移动何时提供更好的性能呢?
再一次,你想错了。移动构造函数用于移动,复制构造函数用于复制。对于某些类,移动构造函数可能更快(例如,如果您可以切换分配的缓冲区等);对于某些人来说,事实并非如此。
延伸阅读:Andrzej的C++博客上对这两种CTOR的合理介绍。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- OpenMP阵列性能较差
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 复制列表初始化的隐式转换的等级是多少
- 通过默认复制构造函数比较 C++ 字符串是否会影响性能,原因为何?
- 自定义类中的移动与复制性能
- 复制 CTOR 与赋值运算符以初始化对象(性能)
- C++将 2D 阵列的一部分复制到另一个 2D 阵列,性能
- 对于阵列复制,const&的性能更好吗?
- 在将 char 数组复制到字符串期间节省 CPU 周期(提高性能)
- std::copy 和容器的复制构造函数之间是否存在任何性能差异?
- 矢量排序/唯一/擦除与复制到无序集的性能
- 使用fread/fwrite将文件复制到USB的性能
- 数组大小和复制性能
- 指针函数参数在C++中的复制和性能