使用ParseFromZeroCopyStream
加载写入大缓冲区的文件时,我遇到了内存使用率高的问题。此外,下面的代码片段使用60Gb ++的RAM但由于系统在达到RAM限制后冻结而失败。
仅供参考,我使用protobuf作为DLL。
scene.proto
syntax = "proto3";
package Recipe;
option cc_enable_arenas = true;
message Scene
{
repeated int32 image_data = 1 [packed=true];
}
source.cpp
#include <iostream>
#include <fstream>
#include <ostream>
#include <istream>
#include <string>
#include <cstdint>
#include "Scene.pb.h"
#include <google\protobuf\io\zero_copy_stream_impl.h>
#include <google\protobuf\io\gzip_stream.h>
#include <google\protobuf\arena.h>
int const _MIN = 0;
int const _MAX = 255;
unsigned int const _SIZE = 1280000000;
//unsigned int const _SIZE = 2000;
unsigned int const _COMPRESSION_LEVEL = 6;
void randWithinUnsignedCharSize(uint8_t * buffer, unsigned int size)
{
for (size_t i = 0; i < size; ++i)
{
buffer[i] = i;
}
}
using namespace google::protobuf::io;
int main()
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
{
google::protobuf::Arena arena;
Recipe::Scene * scene = google::protobuf::Arena::CreateMessage<Recipe::Scene>(&arena);
uint8_t * imageData = new uint8_t[_SIZE];
randWithinUnsignedCharSize(imageData, _SIZE);
scene->mutable_image_data()->Resize(_SIZE, 0);
for (size_t i = 0; i < _SIZE; i++)
{
scene->set_image_data(i, imageData[i]);
}
std::cout << "done saving data to repeated field.\n";
{
std::fstream output("data.txt", std::ios::out | std::ios::trunc | std::ios::binary);
OstreamOutputStream outputFileStream(&output);
GzipOutputStream::Options options;
options.format = GzipOutputStream::GZIP;
options.compression_level = _COMPRESSION_LEVEL;
GzipOutputStream gzipOutputStream(&outputFileStream, options);
if (!scene->SerializeToZeroCopyStream(&gzipOutputStream)) {
std::cerr << "Failed to write scene." << std::endl;
return -1;
}
}
delete[] imageData;
}
std::cout << "Finish serializing into data.txt\n";
{
google::protobuf::Arena arena1;
Recipe::Scene * scene1 = google::protobuf::Arena::CreateMessage<Recipe::Scene>(&arena1);
{
std::fstream input("data.txt", std::ios::in | std::ios::binary);
IstreamInputStream inputFileStream(&input);
GzipInputStream gzipInputStream(&inputFileStream);
if (!scene1->ParseFromZeroCopyStream(&gzipInputStream)) {
std::cerr << "Failed to parse scene." << std::endl;
return -1;
}
}
std::cout << "scene1->imagedata_size() " << scene1->image_data_size() << std::endl;
}
google::protobuf::ShutdownProtobufLibrary();
return 0;
}