Last active
November 7, 2016 19:14
-
-
Save duizendnegen/875cfa14e95cb09f7cb6fab893b4ea81 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define CAPNP_LITE 1 | |
#include "proto.capnp.h" | |
#include <stdio.h> | |
#include <iostream> | |
#include <fstream> | |
#include <vector> | |
#include <numeric> | |
#include <string> | |
#include <capnp/message.h> | |
#include <capnp/serialize.h> | |
#include <kj/std/iostream.h> | |
#include <kj/exception.h> | |
#include <boost/timer/timer.hpp> | |
#include <boost/crc.hpp> | |
#define SIZE 10000000 | |
#define WRITE_BLOCK_BUFFER_SIZE 1024 | |
void binary_serialize(const std::vector<std::uint32_t>& data) { | |
std::cout << "Writing as binary to disk" << std::endl; | |
std::ofstream out_stream("binary.bin", std::ios::binary); | |
const std::uint64_t size = data.size(); | |
out_stream.write(reinterpret_cast<const char *>(&size), sizeof(size)); | |
std::uint32_t write_buffer[WRITE_BLOCK_BUFFER_SIZE]; | |
std::size_t buffer_len = 0; | |
for (const auto entry : data) | |
{ | |
write_buffer[buffer_len++] = entry; | |
if (buffer_len >= WRITE_BLOCK_BUFFER_SIZE) | |
{ | |
out_stream.write(reinterpret_cast<const char *>(write_buffer), | |
WRITE_BLOCK_BUFFER_SIZE * sizeof(std::uint32_t)); | |
buffer_len = 0; | |
} | |
} | |
if (buffer_len > 0) | |
out_stream.write(reinterpret_cast<const char *>(write_buffer), | |
buffer_len * sizeof(std::uint32_t)); | |
} | |
void binary_deserialize(std::vector<std::uint32_t>& data) { | |
std::cout << "Reading as binary from disk" << std::endl; | |
std::ifstream in_stream("binary.bin", std::ios::binary); | |
std::uint64_t count = 0; | |
in_stream.read(reinterpret_cast<char *>(&count), sizeof(count)); | |
data.resize(count); | |
if (count) | |
in_stream.read(reinterpret_cast<char *>(&data[0]), sizeof(std::uint32_t) * count); | |
} | |
void capnp_serialize(const std::vector<std::uint32_t>& data) { | |
std::cout << "Writing with cap'nproto to disk" << std::endl; | |
::capnp::MallocMessageBuilder message; | |
auto vec = message.initRoot<Vector>(); | |
auto list = vec.initElements(data.size()); | |
std::uint64_t count = 0; | |
for (auto dataIt = data.begin(); | |
dataIt != data.end(); | |
count++, dataIt++) { | |
list.set(count, data[*dataIt]); | |
} | |
std::ofstream out_stream("proto.bin", std::ios::binary); | |
kj::std::StdOutputStream out(out_stream); | |
writeMessage(out, message); | |
} | |
void capnp_deserialize(std::vector<std::uint32_t>& data) { | |
std::cout << "Reading with cap'nproto from disk" << std::endl; | |
std::ifstream in_stream("proto.bin", std::ios::binary); | |
kj::std::StdInputStream in(in_stream); | |
// increase the max data size appropriately, | |
// alternatively an exception is thrown when getting the rood of the message | |
::capnp::ReaderOptions options; | |
options.traversalLimitInWords = 1024 * 1024 * 1024; | |
::capnp::InputStreamMessageReader message(in, options); | |
auto vec = message.getRoot<Vector>(); | |
auto list = vec.getElements(); | |
data.resize(list.size(), 0); | |
std::uint64_t count = 0; | |
for (auto listIt = list.begin(); | |
listIt != list.end(); | |
count++, listIt++) { | |
data[count] = list[*listIt]; | |
} | |
} | |
uint32_t checksum(std::vector<std::uint32_t>& data) { | |
boost::crc_32_type result; | |
std::size_t const len = sizeof(data); | |
result.process_bytes(reinterpret_cast<const char *>(&data[0]), len); | |
return result.checksum(); | |
} | |
int main(int argc, char *argv[]) { | |
std::cout << "Allocating " << SIZE * sizeof(std::uint32_t) << " bytes" << std::endl; | |
std::vector<std::uint32_t> data; | |
data.resize(SIZE, 0); | |
std::uint32_t x = 0; | |
std::cout << "Populating" << std::endl; | |
std::iota(data.begin(), data.end(), 0); | |
std::vector<std::uint32_t> bin_data; | |
std::vector<std::uint32_t> proto_data; | |
auto cx = checksum(data); | |
{ | |
boost::timer::auto_cpu_timer t; | |
binary_serialize(data); | |
} | |
{ | |
boost::timer::auto_cpu_timer t; | |
capnp_serialize(data); | |
} | |
{ | |
boost::timer::auto_cpu_timer t; | |
binary_deserialize(bin_data); | |
} | |
std::cout << "Checksum: " << cx << " = " << checksum(bin_data) << std::endl; | |
{ | |
boost::timer::auto_cpu_timer t; | |
capnp_deserialize(proto_data); | |
} | |
std::cout << "Checksum: " << cx << " = " << checksum(proto_data) << std::endl; | |
std::cout << "Press the 'any' key" << std::endl; | |
std::string confirmation; | |
std::getline(std::cin, confirmation); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@0xce135c685651a010; | |
struct Vector { | |
elements @0 :List(Int32); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment