nlib
msgpack/msgpack2/msgpack2.cpp

静的型を直接MessagePackで読み書きするサンプルです。 読み書きするデータ型が完全に決まっていて性能を重視する場合は、MpObjectを介さずにデータを読み書きすることで高速にデータの読み書きを行うことができます。

サンプルでは以下のようなことを行なっています。

以下がサンプルのソースコードになります。

#include <vector>
#include "nn/nlib/msgpack/JsonStreamGenerator.h"
#include "nn/nlib/msgpack/JsonStreamParser.h"
using nlib_ns::msgpack::MpObject;
using nlib_ns::msgpack::JsonStreamGenerator;
using nlib_ns::msgpack::JsonStreamGeneratorSettings;
using nlib_ns::msgpack::JsonStreamParser;
using nlib_ns::msgpack::JsonStreamParserSettings;
#ifndef VECSIZE
#define VECSIZE (1000000)
#endif
void SetupVector(std::vector<int>* vec) {
vec->clear();
for (int i = 0; i < VECSIZE; ++i) vec->push_back(i);
}
bool ReadWriteMessagePack() {
// Read/Write data via MpObject.
std::vector<int> vec;
std::vector<int> ans;
ans.reserve(VECSIZE);
vec.reserve(VECSIZE);
SetupVector(&vec);
ReallocOutputStream ostr;
ostr.Reserve(VECSIZE * 8);
uint64_t from, to1, to2;
from = GetTickTime();
{
MpObject obj;
obj.Box(vec);
JsonStreamGenerator gen;
JsonStreamGeneratorSettings settings;
settings.msgpack = true;
if (nlib_is_error(gen.Init(settings))) return false;
if (nlib_is_error(gen.Open(&ostr))) return false;
gen.Object(obj);
if (nlib_is_error(gen.Flush())) return false;
if (nlib_is_error(gen.Close())) return false;
}
to1 = GetTickTime();
{
JsonStreamParser parser;
JsonStreamParserSettings settings;
settings.max_array_size = VECSIZE;
ReallocOutputStream::UniquePtrType data;
size_t data_size = ostr.Release(&data);
MemoryInputStream istr(data.get(), data_size);
UniquePtr<MpObject> obj;
parser.Init(settings);
parser.Open(&istr);
if (nlib_is_error(JsonStreamParser::Parse(&parser, obj))) return false;
obj->Unbox(&ans);
}
to2 = GetTickTime();
nlib_printf("time: ReadWriteMessagePack(VECSIZE = %d): write = %" PRIu64 ", read = %" PRIu64
" msec\n",
VECSIZE, to1 - from, to2 - to1);
// Verifies
if (ans != vec) return false;
return true;
}
bool ReadWriteMessagePackDirect() {
// Read/Write data without MpObject. It is faster if possible.
std::vector<int> vec;
std::vector<int> ans;
ans.reserve(VECSIZE);
vec.reserve(VECSIZE);
SetupVector(&vec);
ReallocOutputStream ostr;
ostr.Reserve(VECSIZE * 8);
uint64_t from, to1, to2;
from = GetTickTime();
{
JsonStreamGenerator gen;
JsonStreamGeneratorSettings settings;
settings.msgpack = true;
if (nlib_is_error(gen.Init(settings))) return false;
if (nlib_is_error(gen.Open(&ostr))) return false;
gen.Int32Array(&vec[0], vec.size());
if (nlib_is_error(gen.Flush())) return false;
if (nlib_is_error(gen.Close())) return false;
}
to1 = GetTickTime();
{
JsonStreamParser parser;
JsonStreamParserSettings settings;
settings.max_array_size = VECSIZE;
ReallocOutputStream::UniquePtrType data;
size_t data_size = ostr.Release(&data);
MemoryInputStream istr(data.get(), data_size);
parser.Init(settings);
parser.Open(&istr);
JsonStreamParser::Event ev = parser.Next();
if (ev != JsonStreamParser::EVENT_START_ARRAY) return false;
while ((ev = parser.Next()) != JsonStreamParser::EVENT_END_ARRAY) {
int num;
if (JsonStreamParser::ToInt32(parser.GetToken(), &num) != 0) return false;
ans.push_back(num);
}
if (nlib_is_error(parser)) return false;
}
to2 = GetTickTime();
nlib_printf("time: ReadWriteMessagePackDirect(VECSIZE = %d): write = %" PRIu64
", read = %" PRIu64 " msec\n",
VECSIZE, to1 - from, to2 - to1);
// Verifies
if (ans != vec) return false;
return true;
}
bool SampleMain(int, char**) { return ReadWriteMessagePack() && ReadWriteMessagePackDirect(); }
NLIB_MAINFUNC