我发现asio的buffer的引用语义使用起来不太方便。它要求用户在堆中分配数据,但对于小尺寸数据(例如100字节),在堆栈上分配并多次复制(我认为使用asio时复制次数应该小于3次)会比调用一个新操作。 例如:
class MyData {
std::vector<char> data;
};
void hander(Request req) {
MyData d;
async_write(buffer(d.data)...);
} // oops, d was destroyed, but the actual write have not execute
// this is ok, but awkward and poor performance if data is very small
void hander(Request req) {
shared_ptr<MyData> d(new MyData());
async_write(buffer(d->data)...bind(&X::handle_write, this, d);
}
void handle_write(shared_ptr<MyData> s) {
}
为什么asio没有提供可以进行深拷贝的缓冲区?它会节省性能复制时间,但对于应用程序发送大量小数据,性能应该会更差
在其文档中,连接对象有一个用于保存数据的成员,但对于大多数应用程序来说,数据成员是不够的。当应用程序可以随时写入数据时需要使用队列(不喜欢HTTP等半双工协议(protocol)),否则数据可能会被下次写入覆盖。所以如果队列是Queue,那还需要调用new,如果队列是Queue,那还是需要copy
最佳答案
Boost.Asio 的缓冲区类型对实际内存需要分配的位置没有任何要求。它只是要求它所代表的内存是连续的,当它不连续时,则需要使用缓冲区序列。
Boost.Asio提供buffer_copy
它可用于执行从一个缓冲区或缓冲区序列到另一个缓冲区或缓冲区序列的深度复制。纯粹是猜测,但 Asio 可能不会提供拥有底层内存的缓冲区,因为:
- 内存使用特征因应用程序而异。是否存在良好的默认分配或所有权策略可供使用尚不清楚。
boost::buffer()
提供了一种从各种类型(原始内存、c 数组、boost/std::array
)创建 Boost.Asio 缓冲区的便捷方法、std::vector
和std::string
)。其中一些类型已经提供了自定义分配的方法以及执行深度复制的方法(复制构造函数、赋值、std::copy
)。- Boost.Asio操作是根据缓冲区序列的概念/类型要求来实现的,例如MutableBufferSequence ,不是实际类型,例如
boost::asio::mutable_buffers
。因此,用户可以自由地使用自己的类型和内存管理,只要满足类型要求即可。这是 reference counted buffer 的官方示例.
分析并确定分配和拷贝是瓶颈后,然后考虑采用旨在解决特定问题的技术:
- Memory Pools将允许重用内存,而不是将内存释放回空闲存储。
- 在某些情况下,引用计数缓冲区可能无需执行深层复制。考虑使用官方示例或
boost/std::shared_ptr
。这些甚至可以由池通过使用自定义删除器管理的类型使用。 - 对于唯一所有权,
std::unique_ptr
和/或 move-semantics 也可能会删除不必要的深层拷贝。
关于c++ - asio缓冲区深拷贝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17341301/