Sil*_*cer 6 c++ qt memory-management qbytearray
我只是试图优化一些通信堆栈.我使用的是Qt 5.3.2/VS2013.
堆栈使用QByteArray作为数据缓冲区.我打算在数据大小增加时使用capacity()和reserve()方法来减少不必要的内部缓冲区重新分配.然而,QByteArray的行为结果是不一致的.保留的空间有时似乎被隐含地挤压了.
我可以提取以下演示,应用字符串追加,字符串赋值和附加到三个缓冲区的字符.这些单个操作似乎保留了内部缓冲区大小(使用获得capacity()).但是,当将这三个操作中的每一个应用于同一QByteArray时,保留的大小会发生变化.这种行为对我来说是随机的:
QByteArray x1; x1.reserve(1000);
x1.append("test");
qDebug() << "x1" << x1.capacity() << x1;
QByteArray x2; x2.reserve(1000);
x2 = "test";
qDebug() << "x2" << x2.capacity() << x2;
QByteArray x3; x3.reserve(1000);
x3.append('t');
qDebug() << "x3" << x3.capacity() << x3;
QByteArray x4; x4.reserve(1000);
x4.append("test");
x4.append('t');
x4 = "test";
qDebug() << "x4" << x4.capacity() << x4;
Run Code Online (Sandbox Code Playgroud)
预期的产出是:
x1 1000 "test"
x2 1000 "test"
x3 1000 "t"
x4 1000 "test"
Run Code Online (Sandbox Code Playgroud)
但实际输出是:
x1 1000 "test"
x2 1000 "test"
x3 1000 "t"
x4 4 "test"
Run Code Online (Sandbox Code Playgroud)
有没有人对这种奇怪的行为有解释?
更新:看起来clear()也丢弃预订.
好的。我想我已经得到了我需要的信息。
显然,除了所有方法之外,预订并没有得到维护。特别clear()是operator=()似乎取消预订。在这种情况下,operator=()由于 所使用的数据隐式共享,实际上不可能保留保留operator=(QByteArray)。
这也意味着 QByteArray 的预留机制是针对不同的用例而设计的。尝试使保留在 QByteArray 对象的整个生命周期中持续存在是很困难的。
对于我的用例,似乎有一个解决方法,使用truncate(0)而不是clear()or operator=():
QByteArray buffer;
buffer.reserve(1000);
buffer.append("foo");
qDebug() << "buffer" << buffer.capacity() << buffer;
buffer.truncate(0);
buffer.append("bar");
qDebug() << "buffer" << buffer.capacity() << buffer;
Run Code Online (Sandbox Code Playgroud)
这打印:
buffer 1000 "foo"
buffer 1000 "bar"
Run Code Online (Sandbox Code Playgroud)
(感谢亚历杭德罗)
reserve()更稳定的方法是在每个数据收集/附加序列之前进行调用。这不会在 QByteArray 的整个生命周期中将重新分配减少到一次,但至少它对每个数据序列只使用一次重新分配,否则需要多次重新分配。我认为这是一个可以接受的解决方法。
无论如何,在 Qt 容器上使用之前,reserve()应该详细测试其行为,否则容器的行为可能与预期有很大不同。这也很重要,因为这些基本的实现细节没有记录在案,并且可能会在未来的 Qt 版本中更改,恕不另行通知。
| 归档时间: |
|
| 查看次数: |
936 次 |
| 最近记录: |