Skip to content

Instantly share code, notes, and snippets.

@Oipo
Created April 7, 2017 12:54
Show Gist options
  • Save Oipo/d9dd314f475d9aa725317ffac9a72fac to your computer and use it in GitHub Desktop.
Save Oipo/d9dd314f475d9aa725317ffac9a72fac to your computer and use it in GitHub Desktop.
Simple benchmark comparing cereal json vs rapidjson included in cereal.
99999
199999
299999
399999
499999
599999
699999
799999
899999
999999
rapidjson serialize took 422 ms
99999
199999
299999
399999
499999
599999
699999
799999
899999
999999
rapidjson deserialize took 1486 ms
99999
199999
299999
399999
499999
599999
699999
799999
899999
999999
json cereal serialize took 2554 ms
99999
199999
299999
399999
499999
599999
699999
799999
899999
999999
json cereal deserialize took 3724 ms
// compile with: g++ -std=c++11 -O3 -march=native -I ./cereal/include -I ./cereal/include/cereal/external rapidjson_cereal.cpp -o rapidjson
// results in output.txt are acquired on linux mint 18.1 64 bit with g++ version 5.4.0
#include <sys/time.h>
#include <cereal/archives/json.hpp>
#include <cereal/types/string.hpp>
#include <sched.h>
#include <unistd.h>
using namespace std;
using namespace rapidjson;
constexpr uint32_t iterations = 1000000;
uint64_t get_time() {
struct timeval tv;
gettimeofday(&tv, NULL);
uint64_t ret = tv.tv_usec;
/* Convert from micro seconds (10^-6) to milliseconds (10^-3) */
ret /= 1000;
/* Adds the seconds (10^0) after converting them to milliseconds (10^-3) */
ret += (tv.tv_sec * 1000);
return ret;
}
class rapidjson_data {
public:
unsigned type;
bool server;
unsigned sender_id;
string username;
string password;
string email;
rapidjson_data() : type(), server(), sender_id(), username(), password(), email() {}
rapidjson_data(uint8_t type, bool server, uint8_t sender_id, string username, string password, string email) :
type(type), server(server), sender_id(sender_id), username(username), password(password), email(email)
{}
rapidjson_data(rapidjson_data&& o) : type(move(o.type)), server(move(o.server)), sender_id(move(o.sender_id)),
username(move(o.username)), password(move(o.password)), email(move(o.email))
{}
template <typename Writer>
void Serialize_Rapidjson(Writer& writer) const {
writer.StartObject();
writer.String("type");
writer.Uint(type);
writer.String("server");
writer.Bool(server);
writer.String("sender_id");
writer.Uint(sender_id);
writer.String("username");
writer.String(username.c_str(), static_cast<SizeType>(username.length()));
writer.String("password");
writer.String(password.c_str(), static_cast<SizeType>(password.length()));
writer.String("email");
writer.String(email.c_str(), static_cast<SizeType>(email.length()));
writer.EndObject();
}
template<class Archive>
void serialize(Archive & archive)
{
archive( CEREAL_NVP(type), CEREAL_NVP(server), CEREAL_NVP(sender_id), CEREAL_NVP(username), CEREAL_NVP(password), CEREAL_NVP(email) ); // serialize things by passing them to the archive
}
};
auto data = rapidjson_data(1u, true, 2u, "user", "pass", "email");
void cereal_serialize() {
stringstream ss;
{
cereal::JSONOutputArchive archive(ss);
archive(data);
}
}
void cereal_deserialize() {
stringstream ss;
ss << "{ \"value0\": { \"type\": 1, \"server\": true, \"sender_id\": 2, \"username\": \"user\", \"password\": \"pass\", \"email\": \"email\" } }";
auto empty_data = rapidjson_data();
{
cereal::JSONInputArchive archive(ss);
archive(empty_data);
}
if(empty_data.username != "user") {
throw runtime_error("boo!");
}
}
void rapidjson_serialize() {
StringBuffer sb;
PrettyWriter<StringBuffer> writer(sb);
writer.SetIndent(' ', 4);
writer.SetMaxDecimalPlaces(PrettyWriter<StringBuffer>::kDefaultMaxDecimalPlaces);
data.Serialize_Rapidjson(writer);
}
void rapidjson_deserialize() {
stringstream ss;
ss << "{ \"type\": 1, \"server\": true, \"sender_id\": 2, \"username\": \"user\", \"password\": \"pass\", \"email\": \"email\" }";
Document d;
d.Parse(ss.str().c_str());
auto empty_data = rapidjson_data(d["type"].GetUint(), d["server"].GetBool(), d["sender_id"].GetUint(), d["username"].GetString(), d["password"].GetString(), d["email"].GetString());
if(empty_data.username != "user") {
throw std::runtime_error("boo!");
}
}
int main() {
ios::sync_with_stdio(false);
auto stopwatch = get_time();
for(int i = 0; i < iterations; i++) {
rapidjson_serialize();
if((i+1) % (iterations/10) == 0) {
cout << i << endl;
}
}
auto total_time = get_time() - stopwatch;
cout << "rapidjson serialize took " << total_time << " ms" << endl;
stopwatch = get_time();
for(int i = 0; i < iterations; i++) {
rapidjson_deserialize();
if((i+1) % (iterations/10) == 0) {
cout << i << endl;
}
}
total_time = get_time() - stopwatch;
cout << "rapidjson deserialize took " << total_time << " ms" << endl;
stopwatch = get_time();
for(int i = 0; i < iterations; i++) {
cereal_serialize();
if((i+1) % (iterations/10) == 0) {
cout << i << endl;
}
}
total_time = get_time() - stopwatch;
cout << "json cereal serialize took " << total_time << " ms" << endl;
stopwatch = get_time();
for(int i = 0; i < iterations; i++) {
cereal_deserialize();
if((i+1) % (iterations/10) == 0) {
cout << i << endl;
}
}
total_time = get_time() - stopwatch;
cout << "json cereal deserialize took " << total_time << " ms" << endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment