[英]Boost: Re-using/clearing text_iarchive for de-serializing data from Asio:receive()
这是我当前的功能,可以反序列化通过Boost:Asio UDP传输接收的数据。 它可以完美运行, 但是性能却很差。 每秒大约4000次调用将占用约16%的CPU,这是I7的全线程。
对代码运行性能测试表明,此行使用了超过95%的cpu时间:
text_iarchive LLArchive(LLStream);
我的问题很简单:是否有一种方法可以重用text_iarchive,而不必每次调用该函数时都创建一个新的? (在C#中,通过反序列化数据所需的内存流和其他变量,可能会发生类似的事情)。 我搜索了Boost文档,却没有提及任何类似的东西。
我本质上想要的是将函数放在一个类中,并具有尽可能多的变量定义为成员,这些成员可以通过重新初始化(清除缓冲区/流,重新设置数据等)在函数内部简单使用。 这会提高性能吗? 更改传递到存档中的流是否足以解决问题(将它绑定到某个地方,以便如果我们更改传递的流,则存档本身设置的流也会发生变化)吗?
可能吗?
非常感谢您的宝贵时间!
全功能代码:
using namespace boost::archive;
using namespace boost::iostreams;
Packet InboundStreamToInternalPacket(boost::array<char, 5000> inboundStream)
{
Packet receivedPacket;
basic_array_source<char> arraySourceLL(inboundStream.data(), inboundStream.size());
stream<basic_array_source<char>> LLStream(arraySourceLL);
text_iarchive LLArchive(LLStream);
LLArchive >> receivedPacket;
return receivedPacket;
}
编辑1:
尝试重新关闭和打开流,就像添加了新的源一样,在反序列化到第二个Packet时,崩溃并显示为“ boost :: archive :: archive_exception在内存位置xxxxxx”。
Packet InboundStreamToInternalPacket(boost::array<char, 5000> inboundStream)
{
Packet receivedPacket;
Packet receivedPacket2;
basic_array_source<char> arraySourceLL(inboundStream.data(), inboundStream.size());
stream<basic_array_source<char>> LLStream;
LLStream.open(arraySourceLL);
text_iarchive LLArchive(LLStream);
LLArchive >> receivedPacket;
LLStream.close();
LLStream.open(arraySourceLL);
LLArchive >> receivedPacket2;
return receivedPacket;
}
不,没有这样的方法。
但是,与MemoryStream
的比较被破坏了,因为存档位于流上方 。
您可以重新使用流。 因此,如果执行与MemoryStream完全相同的并行操作,例如在固定缓冲区上进行boost::iostreams::array_sink
和/或boost::iostreams::array_source
,则可以在下一个(反)序列化中轻松地重用该缓冲区。
请参阅此概念证明:
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <sstream>
namespace bar = boost::archive;
namespace bio = boost::iostreams;
struct Packet {
int i;
template <typename Ar> void serialize(Ar& ar, unsigned) { ar & i; }
};
namespace Reader {
template <typename T>
Packet deserialize(T const* data, size_t size) {
static_assert(boost::is_pod<T>::value , "T must be POD");
static_assert(boost::is_integral<T>::value, "T must be integral");
static_assert(sizeof(T) == sizeof(char) , "T must be byte-sized");
bio::stream<bio::array_source> stream(bio::array_source(data, size));
bar::text_iarchive ia(stream);
Packet result;
ia >> result;
return result;
}
template <typename T, size_t N>
Packet deserialize(T (&arr)[N]) {
return deserialize(arr, N);
}
template <typename T>
Packet deserialize(std::vector<T> const& v) {
return deserialize(v.data(), v.size());
}
template <typename T, size_t N>
Packet deserialize(boost::array<T, N> const& a) {
return deserialize(a.data(), a.size());
}
}
template <typename MutableBuffer>
void serialize(Packet const& data, MutableBuffer& buf)
{
bio::stream<bio::array_sink> s(buf.data(), buf.size());
bar::text_oarchive ar(s);
ar << data;
}
int main() {
boost::array<char, 1024> arr;
for (int i = 0; i < 100; ++i) {
serialize(Packet { i }, arr);
Packet roundtrip = Reader::deserialize(arr);
assert(roundtrip.i == i);
}
std::cout << "Done\n";
}
有关boost序列化的一般优化,请参见:
boost::archive::no_codecvt
, boost::archive::no_header
, 禁用跟踪等)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.