较大的对象复制速度是否较慢(C++)
Are larger objects slower to copy (C++)?
如果你想在C++中复制一个对象(在堆栈上),复制更大的对象会更慢吗?是立即复制对象,还是以迭代方式复制数据的字节?:
class Small {
public:
int stuff[32];
};
class Big {
public:
int stuff[1024];
};
...
Small small;
Big big;
Small small2 = Small(small); //Faster?
Big big2 = Big(big); //Slower?
对不起,现在我没有时间测试这个。
是的,较大的对象比较小的对象需要更多的时间来复制或移动。
一个由32个整数组成的数组需要32次操作才能复制或移动
一个由1024个整数组成的数组需要1024次操作才能复制或移动。
问题是时差是否显著。在现代处理器中,大多数复制操作都在纳秒量级。那么,(大约)1000纳秒会影响你的程序吗?这取决于情况。如果您的程序等待I/O的时间为毫秒或更长,则差异可能并不显著。
编辑1:
所需的空间量可能比复制所花费的时间更重要。
大对象的一般经验法则是让它们坐着并将指针传递给对象;不要复制或移动大型物体。指针比大型对象占用的空间更小,复制和移动速度更快。也更喜欢引用指针。
编辑2:-堆栈
复制到堆栈取决于处理器和编译器的协议。不需要堆叠。
在使用堆栈传递参数和局部变量分配的经典实现中,除了复制对象外,还需要增加堆栈指针变量。
因此,如果我将32个整数传递给一个函数,那么将有32个复制操作加上对堆栈指针的加法操作。
通常,堆栈空间的关注比将大型对象推送(复制)到堆栈上所需的时间更重要。
根据优化级别和其他属性,编译器可能能够通过指针传递对象。
并不是LARGER对象需要更长的时间来复制,而是需要进行复制所需的处理。
是,正在复制
char [4096] ;
通常需要比复制更长的时间
char [32] ;
然而,还有其他事情可能需要更长的时间。如果复制构造函数和赋值运算符进行大量其他处理,那么这通常比四处移动数据更需要计算量。
复制一个由32个整数组成的数组并不一定意味着32条指令。某些处理器具有块移动指令。但是,一个块移动指令可能需要多个周期才能执行。
需要复制的字节越多,所需时间就越长。这对你的整体表现是否重要则另当别论。真正的杀手是拷贝需要动态内存分配。字节的直接拷贝通常不会那么糟糕,无论是在堆栈还是堆上(只要目标内存已经分配)。在堆栈上放置大数组时要小心。
不一定,尽管很明显,较大的对象意味着需要移动更多的数据,因此需要更长的时间,但在某些情况下,复制的开销更重要。。。
例如。
Big b1;
Big b2 = b1;
将是快速的,堆栈到堆栈的副本真的很快分配内存,副本只是一组快速的CPU指令来复制数据,通常是在优化的专用指令串中。
Small s1;
Small* s2 = new Small(s1);
这可能没有那么快,您必须在相对昂贵的堆上分配内存,然后复制数据。显然,如果Big对象真的很大(我不能告诉你这一点是什么,这取决于堆碎片、堆实现——池会更快,执行堆栈复制所需的时间),那么内存复制加分配会比上一个例子便宜。
然后是复制构造方面,您的对象,但大多数对象都有更多的成员变量,以及一个单独处理每个变量的复制ctor,有些对象甚至有执行复制所需的专用例程,例如记录复制或锁定一些无法并行访问的共享资源。
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 无论条件是否为true,if总是在c++中执行
- 如何找到大小'x'数组是否完全填充,在C++?
- 检查值是否在集合p1和p2中,但不在p3中
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- C/C++预处理器是否可以检测一些编译器选项
- 是否可以用"iostream"包装现有的TCP/OOpenSSL会话