最快的c ++序列化?

Jay*_*Jay 19 c++ serialization

大家早上好,

我正在为c ++寻找一种非常快速的二进制序列化技术.我只需要序列化对象中包含的数据(没有指针等).我希望它尽可能快.如果它特定于x86硬件是可以接受的.

我熟悉这样做的C方法.作为一项测试,我在板凳上标记了几种技术.我发现C方法比我实现的最好的C++方法快40%.

有关如何改进C++方法(或执行此操作的库)的任何建议?任何可用于内存映射文件的东西?

谢谢

// c style writes
{
   #pragma pack(1)
   struct item
   {
      uint64_t off;
      uint32_t size;
   } data;
   #pragma pack

   clock_t start = clock();

   FILE* fd = fopen( "test.c.dat", "wb" );
   for ( long i = 0; i < tests; i++ )
   {
      data.off = i;
      data.size = i & 0xFFFF;
      fwrite( (char*) &data, sizeof(data), 1, fd );
   }
   fclose( fd );

   clock_t stop = clock();

   double d = ((double)(stop-start))/ CLOCKS_PER_SEC;
   printf( "%8.3f seconds\n", d );
}
Run Code Online (Sandbox Code Playgroud)

测试约1.6秒= 10000000

// c++ style ofstream writes

// define a DTO class
class test
{
public:
   test(){}

   uint64_t off;
   uint32_t size;

   friend std::ostream& operator<<( std::ostream& stream, const test& v );
};

// write to the stream
std::ostream& operator<<( std::ostream &stream,  const test& v )
{
   stream.write( (char*)&v.off, sizeof(v.off) );
   stream.write( (char*)&v.size, sizeof(v.size) );
   return stream;
}

{
   test data;

   clock_t start = clock();

   std::ofstream out;
   out.open( "test.cpp.dat", std::ios::out | std::ios::trunc | std::ios::binary );
   for ( long i = 0; i < tests; i++ )
   {
      data.off = i;
      data.size = i & 0xFFFF;
      out << data;
   }
   out.close();

   clock_t stop = clock();

   double d = ((double)(stop-start))/ CLOCKS_PER_SEC;
   printf( "%8.3f seconds\n", d );
}
Run Code Online (Sandbox Code Playgroud)

测试约2.6秒= 10000000

Han*_*ant 16

只是有少数真实情况是重要的.您只需序列化以使您的对象与某种外部资源兼容.磁盘,网络等.在资源上传输序列化数据的代码总是比序列化对象所需的代码慢几个数量级.如果您将序列化代码的速度提高了两倍,那么您的整体操作速度不会超过0.5%,即可.这既不是风险也不是努力.

测量三次,切一次.


小智 6

如果要执行的任务是真正的序列化,您可以查看Google的Protocol Buffers.它们提供了C++类的快速序列化.该网站还提到了一些替代库,例如boost.serialization(当然,只表示协议缓冲区在大多数情况下都优于它们;-)

  • Protocol Buffers(尽管我很喜欢它)并不是真正的序列化,它更多的是用于消息传递。不同之处在于,对于协议缓冲区,您定义了一个 Message 类,而在序列化中没有中间表示。 (2认同)

Bri*_*nar 1

有什么方法可以利用保持不变的事物吗?

我的意思是,您只是想尽可能快地运行“test.c.dat”,对吧?您可以利用文件在序列化尝试之间不会更改的事实吗?如果您尝试一遍又一遍地序列化同一个文件,您可以基于此进行优化。我可以使第一次序列化尝试花费与您相同的时间,再加上另一次检查的一点额外时间,然后如果您尝试在相同的输入上再次运行序列化,我可以使我的第二次运行比第一次。

我知道这可能只是一个精心设计的示例,但您似乎专注于让语言尽快完成您的任务,而不是问“我需要再次完成这个任务吗?”的问题。这种方法的背景是什么?

我希望这是有帮助的。

-布莱恩·J·斯蒂纳尔-