У меня проблемы с использованием буферов протокола для хранения больших объектов (в этом примере они занимают около 200 МБ при сериализации в двоичные файлы). Мне кажется, что реализация C ++ требует гораздо больше, чем 200 МБ места для их хранения, и я не уверен, ожидается ли это или я делаю что-то не так.
Я использую буфер протокола версии 3.5.1. Вот рабочий пример.
Я ожидаю, что для хранения 5 копий сообщения protobuf в памяти должно быть достаточно ~ 1 ГБ памяти, хотя из приведенного ниже примера кажется, что для кода требуется от 5 до 10 ГБ. Это недостаток protobuf, ошибка или я что-то не так делаю?
Вот мой файл cpp.
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <iostream>
#include <string>
#include "../generated_src/leviosa.pb.h"
template <class ProtoMessage>
ProtoMessage deserializeProtobufFromFile(std::string filename) {
ProtoMessage m;
std::string s_json;
std::fstream input(filename, std::ios::in | std::ios::binary);
if (!input) {
throw std::runtime_error(filename + ": file not found.");
} else if (!m.ParseFromIstream(&input)) {
throw std::runtime_error("Failed to parse " + filename +
" as binary protobuf.");
}
return m;
}
using namespace std;
using namespace leviosa;
int main(int argc, char* argv[]) {
OfflineOutput proto0 =
deserializeProtobufFromFile<OfflineOutput>("offline0.lev");
cout << "Read from file completed." << endl;
auto p1(proto0);
cout << "First copy completed." << endl;
auto p2(p1);
cout << "Another copy completed." << endl;
auto p3(p1);
cout << "Another copy completed." << endl;
auto p4(p1);
cout << "Another copy completed." << endl;
cout << "Done." << endl;
}
Вот (часть) файл прото:
syntax = "proto3";
package leviosa;
message OleSender{
int64 a = 1;
int64 b = 2;
}
message OleReceiver{
int64 x = 1;
int64 z = 2;
}
message Ole{
oneof ole_oneof {
OleSender sender = 1;
OleReceiver receiver = 2;
}
}
message OleVector{
repeated Ole ole = 1;
}
message WatchInfoPerServer{
bytes prg = 1;
OleVector oles = 2;
int64 degree_test_blind_share = 4;
int64 perm_test_blind_share = 5;
}
message OfflineOutput{
repeated bytes prg_seeds = 1;
repeated OleVector oles_for_servers = 2;
bytes degree_test_blind_poly = 3;
bytes perm_test_blind_shares = 4;
oneof commit {
bytes commitment = 5;
bytes randomness_committed = 6;
}
map<int32,WatchInfoPerServer> watchlist = 7;
}
Это пример запуска моей программы. Он работает без проблем с 10 ГБ памяти, но прерывается с 5 ГБ:
$ls -al offline0.lev
-rw-rw-r-- 1 antonio antonio 186560583 Aug 27 17:57 offline0.lev
$ ulimit -v 10000000
$ ./test
Read from file completed.
First copy completed.
Another copy completed.
Another copy completed.
Another copy completed.
Done.
$ ulimit -v 5000000
$ ./test
Read from file completed.
First copy completed.
Another copy completed.
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted (core dumped)
Любая помощь приветствуется