Skip to content

Commit 73b3e42

Browse files
committed
Add Cap'n Proto to benchmark.
Results: $ ./test 100000 performing 100000 iterations thrift-binary: version = 0.9.1 thrift-binary: size = 17017 bytes thrift-binary: time = 9253 milliseconds thrift-compact: version = 0.9.1 thrift-compact: size = 11597 bytes thrift-compact: time = 12249 milliseconds protobuf: version = 2006000 protobuf: size = 12571 bytes protobuf: time = 9349 milliseconds capnproto: version = 5002 capnproto: size = 17768 bytes capnproto: time = 5 milliseconds boost: version = 105600 boost: size = 17470 bytes boost: time = 8942 milliseconds msgpack: version = 0.5.9 msgpack: size = 11902 bytes msgpack: time = 6669 milliseconds cereal: size = 17416 bytes cereal: time = 3608 milliseconds avro: size = 12288 bytes avro: time = 8236 milliseconds
1 parent 651efeb commit 73b3e42

File tree

5 files changed

+401
-1
lines changed

5 files changed

+401
-1
lines changed

CMakeLists.txt

+33-1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,22 @@ include_directories(${protobuf_PREFIX}/include)
9999
set(PROTOBUF_LIBRARIES ${protobuf_PREFIX}/lib/libprotobuf.a)
100100
set(PROTOBUF_GENERATOR ${protobuf_PREFIX}/bin/protoc)
101101

102+
set(capnproto_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/external/capnproto)
103+
ExternalProject_Add(
104+
capnproto
105+
PREFIX ${capnproto_PREFIX}
106+
URL "https://capnproto.org/capnproto-c++-0.5.2.tar.gz"
107+
URL_MD5 "84dcb55dba3f60b0f85734fd0e502401"
108+
CONFIGURE_COMMAND CXX=${CMAKE_CXX_COMPILER} CC=${CMAKE_C_COMPILER} ${capnproto_PREFIX}/src/capnproto/configure --prefix=${capnproto_PREFIX} --enable-shared=no
109+
BUILD_COMMAND $(MAKE)
110+
INSTALL_COMMAND $(MAKE) install
111+
BUILD_IN_SOURCE 1
112+
)
113+
include_directories(${capnproto_PREFIX}/include)
114+
set(CAPNPROTO_LIBRARIES ${capnproto_PREFIX}/lib/libcapnp.a ${capnproto_PREFIX}/lib/libkj.a)
115+
set(CAPNPROTO_GENERATOR ${capnproto_PREFIX}/bin/capnp)
116+
set(CAPNPROTO_CPP_GENERATOR ${capnproto_PREFIX}/bin/capnpc-c++)
117+
102118
set(cereal_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/external/cereal)
103119
ExternalProject_Add(
104120
cereal
@@ -131,6 +147,7 @@ set(AVRO_GENERATOR ${avro_PREFIX}/bin/avrogencpp)
131147
set(LINKLIBS ${THRIFT_LIBRARIES}
132148
${MSGPACK_LIBRARIES}
133149
${PROTOBUF_LIBRARIES}
150+
${CAPNPROTO_LIBRARIES}
134151
${BOOST_LIBRARIES}
135152
${AVRO_LIBRARIES}
136153
${CMAKE_THREAD_LIBS_INIT}
@@ -170,6 +187,20 @@ set_source_files_properties(
170187
)
171188
set(PROTOBUF_SERIALIZATION_SOURCES ${cpp_serializers_SOURCE_DIR}/protobuf/test.pb.cc)
172189

190+
add_custom_command(
191+
DEPENDS ${cpp_serializers_SOURCE_DIR}/test.capnp
192+
COMMAND ${CAPNPROTO_GENERATOR}
193+
ARGS compile -I${cpp_serializers_SOURCE_DIR} --src-prefix=${cpp_serializers_SOURCE_DIR} -o${CAPNPROTO_CPP_GENERATOR}:${cpp_serializers_SOURCE_DIR}/capnproto ${cpp_serializers_SOURCE_DIR}/test.capnp
194+
OUTPUT "${cpp_serializers_SOURCE_DIR}/capnproto/test.capnp.c++"
195+
COMMENT "Executing Cap'n Proto compiler"
196+
)
197+
set_source_files_properties(
198+
${cpp_serializers_SOURCE_DIR}/capnproto/test.capnp.c++
199+
${cpp_serializers_SOURCE_DIR}/capnproto/test.capnp.h
200+
PROPERTIES GENERATED TRUE
201+
)
202+
set(CAPNPROTO_SERIALIZATION_SOURCES ${cpp_serializers_SOURCE_DIR}/capnproto/test.capnp.c++)
203+
173204
add_custom_command(
174205
DEPENDS ${cpp_serializers_SOURCE_DIR}/test.json
175206
COMMAND ${AVRO_GENERATOR}
@@ -189,10 +220,11 @@ set(CEREAL_SERIALIZATION_SOURCES ${cpp_serializers_SOURCE_DIR}/cereal/record.cpp
189220
add_executable(test ${cpp_serializers_SOURCE_DIR}/test.cpp
190221
${THRIFT_SERIALIZATION_SOURCES}
191222
${PROTOBUF_SERIALIZATION_SOURCES}
223+
${CAPNPROTO_SERIALIZATION_SOURCES}
192224
${BOOST_SERIALIZATION_SOURCES}
193225
${CEREAL_SERIALIZATION_SOURCES}
194226
${AVRO_SERIALIZATION_SOURCES}
195227
)
196-
add_dependencies(test thrift msgpack protobuf boost cereal avro)
228+
add_dependencies(test thrift msgpack protobuf capnproto boost cereal avro)
197229
target_link_libraries(test ${LINKLIBS})
198230
set_target_properties(test PROPERTIES COMPILE_FLAGS "-std=c++11")

capnproto/test.capnp.c++

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Generated by Cap'n Proto compiler, DO NOT EDIT
2+
// source: test.capnp
3+
4+
#include "test.capnp.h"
5+
6+
namespace capnp {
7+
namespace schemas {
8+
static const ::capnp::_::AlignedData<55> b_b11f3695c22ca61e = {
9+
{ 0, 0, 0, 0, 5, 0, 6, 0,
10+
30, 166, 44, 194, 149, 54, 31, 177,
11+
11, 0, 0, 0, 1, 0, 0, 0,
12+
86, 151, 87, 178, 195, 228, 213, 234,
13+
2, 0, 7, 0, 0, 0, 0, 0,
14+
0, 0, 0, 0, 0, 0, 0, 0,
15+
21, 0, 0, 0, 146, 0, 0, 0,
16+
29, 0, 0, 0, 7, 0, 0, 0,
17+
0, 0, 0, 0, 0, 0, 0, 0,
18+
25, 0, 0, 0, 119, 0, 0, 0,
19+
0, 0, 0, 0, 0, 0, 0, 0,
20+
0, 0, 0, 0, 0, 0, 0, 0,
21+
116, 101, 115, 116, 46, 99, 97, 112,
22+
110, 112, 58, 82, 101, 99, 111, 114,
23+
100, 0, 0, 0, 0, 0, 0, 0,
24+
0, 0, 0, 0, 1, 0, 1, 0,
25+
8, 0, 0, 0, 3, 0, 4, 0,
26+
0, 0, 0, 0, 0, 0, 0, 0,
27+
0, 0, 1, 0, 0, 0, 0, 0,
28+
0, 0, 0, 0, 0, 0, 0, 0,
29+
41, 0, 0, 0, 34, 0, 0, 0,
30+
0, 0, 0, 0, 0, 0, 0, 0,
31+
36, 0, 0, 0, 3, 0, 1, 0,
32+
64, 0, 0, 0, 2, 0, 1, 0,
33+
1, 0, 0, 0, 1, 0, 0, 0,
34+
0, 0, 1, 0, 1, 0, 0, 0,
35+
0, 0, 0, 0, 0, 0, 0, 0,
36+
61, 0, 0, 0, 66, 0, 0, 0,
37+
0, 0, 0, 0, 0, 0, 0, 0,
38+
56, 0, 0, 0, 3, 0, 1, 0,
39+
84, 0, 0, 0, 2, 0, 1, 0,
40+
105, 100, 115, 0, 0, 0, 0, 0,
41+
14, 0, 0, 0, 0, 0, 0, 0,
42+
0, 0, 0, 0, 0, 0, 0, 0,
43+
0, 0, 0, 0, 0, 0, 0, 0,
44+
0, 0, 0, 0, 3, 0, 1, 0,
45+
5, 0, 0, 0, 0, 0, 0, 0,
46+
0, 0, 0, 0, 0, 0, 0, 0,
47+
0, 0, 0, 0, 0, 0, 0, 0,
48+
0, 0, 0, 0, 0, 0, 0, 0,
49+
14, 0, 0, 0, 0, 0, 0, 0,
50+
0, 0, 0, 0, 0, 0, 0, 0,
51+
0, 0, 0, 0, 0, 0, 0, 0,
52+
115, 116, 114, 105, 110, 103, 115, 0,
53+
14, 0, 0, 0, 0, 0, 0, 0,
54+
0, 0, 0, 0, 0, 0, 0, 0,
55+
0, 0, 0, 0, 0, 0, 0, 0,
56+
0, 0, 0, 0, 3, 0, 1, 0,
57+
12, 0, 0, 0, 0, 0, 0, 0,
58+
0, 0, 0, 0, 0, 0, 0, 0,
59+
0, 0, 0, 0, 0, 0, 0, 0,
60+
0, 0, 0, 0, 0, 0, 0, 0,
61+
14, 0, 0, 0, 0, 0, 0, 0,
62+
0, 0, 0, 0, 0, 0, 0, 0,
63+
0, 0, 0, 0, 0, 0, 0, 0, }
64+
};
65+
::capnp::word const* const bp_b11f3695c22ca61e = b_b11f3695c22ca61e.words;
66+
#if !CAPNP_LITE
67+
static const uint16_t m_b11f3695c22ca61e[] = {0, 1};
68+
static const uint16_t i_b11f3695c22ca61e[] = {0, 1};
69+
const ::capnp::_::RawSchema s_b11f3695c22ca61e = {
70+
0xb11f3695c22ca61e, b_b11f3695c22ca61e.words, 55, nullptr, m_b11f3695c22ca61e,
71+
0, 2, i_b11f3695c22ca61e, nullptr, nullptr, { &s_b11f3695c22ca61e, nullptr, nullptr, 0, 0, nullptr }
72+
};
73+
#endif // !CAPNP_LITE
74+
} // namespace schemas
75+
} // namespace capnp
76+
77+
// =======================================================================================
78+
79+
namespace capnp_test {
80+
81+
// Record
82+
#ifndef _MSC_VER
83+
constexpr uint16_t Record::_capnpPrivate::dataWordSize;
84+
constexpr uint16_t Record::_capnpPrivate::pointerCount;
85+
#endif
86+
#if !CAPNP_LITE
87+
constexpr ::capnp::Kind Record::_capnpPrivate::kind;
88+
constexpr ::capnp::_::RawSchema const* Record::_capnpPrivate::schema;
89+
constexpr ::capnp::_::RawBrandedSchema const* Record::_capnpPrivate::brand;
90+
#endif // !CAPNP_LITE
91+
92+
93+
} // namespace
94+

capnproto/test.capnp.h

+210
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
// Generated by Cap'n Proto compiler, DO NOT EDIT
2+
// source: test.capnp
3+
4+
#ifndef CAPNP_INCLUDED_ead5e4c3b2579756_
5+
#define CAPNP_INCLUDED_ead5e4c3b2579756_
6+
7+
#include <capnp/generated-header-support.h>
8+
9+
#if CAPNP_VERSION != 5002
10+
#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library."
11+
#endif
12+
13+
14+
namespace capnp {
15+
namespace schemas {
16+
17+
CAPNP_DECLARE_SCHEMA(b11f3695c22ca61e);
18+
19+
} // namespace schemas
20+
} // namespace capnp
21+
22+
namespace capnp_test {
23+
24+
struct Record {
25+
Record() = delete;
26+
27+
class Reader;
28+
class Builder;
29+
class Pipeline;
30+
31+
struct _capnpPrivate {
32+
CAPNP_DECLARE_STRUCT_HEADER(b11f3695c22ca61e, 0, 2)
33+
#if !CAPNP_LITE
34+
static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand;
35+
#endif // !CAPNP_LITE
36+
};
37+
};
38+
39+
// =======================================================================================
40+
41+
class Record::Reader {
42+
public:
43+
typedef Record Reads;
44+
45+
Reader() = default;
46+
inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}
47+
48+
inline ::capnp::MessageSize totalSize() const {
49+
return _reader.totalSize().asPublic();
50+
}
51+
52+
#if !CAPNP_LITE
53+
inline ::kj::StringTree toString() const {
54+
return ::capnp::_::structString(_reader, *_capnpPrivate::brand);
55+
}
56+
#endif // !CAPNP_LITE
57+
58+
inline bool hasIds() const;
59+
inline ::capnp::List< ::int64_t>::Reader getIds() const;
60+
61+
inline bool hasStrings() const;
62+
inline ::capnp::List< ::capnp::Text>::Reader getStrings() const;
63+
64+
private:
65+
::capnp::_::StructReader _reader;
66+
template <typename, ::capnp::Kind>
67+
friend struct ::capnp::ToDynamic_;
68+
template <typename, ::capnp::Kind>
69+
friend struct ::capnp::_::PointerHelpers;
70+
template <typename, ::capnp::Kind>
71+
friend struct ::capnp::List;
72+
friend class ::capnp::MessageBuilder;
73+
friend class ::capnp::Orphanage;
74+
};
75+
76+
class Record::Builder {
77+
public:
78+
typedef Record Builds;
79+
80+
Builder() = delete; // Deleted to discourage incorrect usage.
81+
// You can explicitly initialize to nullptr instead.
82+
inline Builder(decltype(nullptr)) {}
83+
inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
84+
inline operator Reader() const { return Reader(_builder.asReader()); }
85+
inline Reader asReader() const { return *this; }
86+
87+
inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
88+
#if !CAPNP_LITE
89+
inline ::kj::StringTree toString() const { return asReader().toString(); }
90+
#endif // !CAPNP_LITE
91+
92+
inline bool hasIds();
93+
inline ::capnp::List< ::int64_t>::Builder getIds();
94+
inline void setIds( ::capnp::List< ::int64_t>::Reader value);
95+
inline void setIds(::kj::ArrayPtr<const ::int64_t> value);
96+
inline ::capnp::List< ::int64_t>::Builder initIds(unsigned int size);
97+
inline void adoptIds(::capnp::Orphan< ::capnp::List< ::int64_t>>&& value);
98+
inline ::capnp::Orphan< ::capnp::List< ::int64_t>> disownIds();
99+
100+
inline bool hasStrings();
101+
inline ::capnp::List< ::capnp::Text>::Builder getStrings();
102+
inline void setStrings( ::capnp::List< ::capnp::Text>::Reader value);
103+
inline void setStrings(::kj::ArrayPtr<const ::capnp::Text::Reader> value);
104+
inline ::capnp::List< ::capnp::Text>::Builder initStrings(unsigned int size);
105+
inline void adoptStrings(::capnp::Orphan< ::capnp::List< ::capnp::Text>>&& value);
106+
inline ::capnp::Orphan< ::capnp::List< ::capnp::Text>> disownStrings();
107+
108+
private:
109+
::capnp::_::StructBuilder _builder;
110+
template <typename, ::capnp::Kind>
111+
friend struct ::capnp::ToDynamic_;
112+
friend class ::capnp::Orphanage;
113+
template <typename, ::capnp::Kind>
114+
friend struct ::capnp::_::PointerHelpers;
115+
};
116+
117+
#if !CAPNP_LITE
118+
class Record::Pipeline {
119+
public:
120+
typedef Record Pipelines;
121+
122+
inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
123+
inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
124+
: _typeless(kj::mv(typeless)) {}
125+
126+
private:
127+
::capnp::AnyPointer::Pipeline _typeless;
128+
friend class ::capnp::PipelineHook;
129+
template <typename, ::capnp::Kind>
130+
friend struct ::capnp::ToDynamic_;
131+
};
132+
#endif // !CAPNP_LITE
133+
134+
// =======================================================================================
135+
136+
inline bool Record::Reader::hasIds() const {
137+
return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull();
138+
}
139+
inline bool Record::Builder::hasIds() {
140+
return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull();
141+
}
142+
inline ::capnp::List< ::int64_t>::Reader Record::Reader::getIds() const {
143+
return ::capnp::_::PointerHelpers< ::capnp::List< ::int64_t>>::get(
144+
_reader.getPointerField(0 * ::capnp::POINTERS));
145+
}
146+
inline ::capnp::List< ::int64_t>::Builder Record::Builder::getIds() {
147+
return ::capnp::_::PointerHelpers< ::capnp::List< ::int64_t>>::get(
148+
_builder.getPointerField(0 * ::capnp::POINTERS));
149+
}
150+
inline void Record::Builder::setIds( ::capnp::List< ::int64_t>::Reader value) {
151+
::capnp::_::PointerHelpers< ::capnp::List< ::int64_t>>::set(
152+
_builder.getPointerField(0 * ::capnp::POINTERS), value);
153+
}
154+
inline void Record::Builder::setIds(::kj::ArrayPtr<const ::int64_t> value) {
155+
::capnp::_::PointerHelpers< ::capnp::List< ::int64_t>>::set(
156+
_builder.getPointerField(0 * ::capnp::POINTERS), value);
157+
}
158+
inline ::capnp::List< ::int64_t>::Builder Record::Builder::initIds(unsigned int size) {
159+
return ::capnp::_::PointerHelpers< ::capnp::List< ::int64_t>>::init(
160+
_builder.getPointerField(0 * ::capnp::POINTERS), size);
161+
}
162+
inline void Record::Builder::adoptIds(
163+
::capnp::Orphan< ::capnp::List< ::int64_t>>&& value) {
164+
::capnp::_::PointerHelpers< ::capnp::List< ::int64_t>>::adopt(
165+
_builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value));
166+
}
167+
inline ::capnp::Orphan< ::capnp::List< ::int64_t>> Record::Builder::disownIds() {
168+
return ::capnp::_::PointerHelpers< ::capnp::List< ::int64_t>>::disown(
169+
_builder.getPointerField(0 * ::capnp::POINTERS));
170+
}
171+
172+
inline bool Record::Reader::hasStrings() const {
173+
return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull();
174+
}
175+
inline bool Record::Builder::hasStrings() {
176+
return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull();
177+
}
178+
inline ::capnp::List< ::capnp::Text>::Reader Record::Reader::getStrings() const {
179+
return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text>>::get(
180+
_reader.getPointerField(1 * ::capnp::POINTERS));
181+
}
182+
inline ::capnp::List< ::capnp::Text>::Builder Record::Builder::getStrings() {
183+
return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text>>::get(
184+
_builder.getPointerField(1 * ::capnp::POINTERS));
185+
}
186+
inline void Record::Builder::setStrings( ::capnp::List< ::capnp::Text>::Reader value) {
187+
::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text>>::set(
188+
_builder.getPointerField(1 * ::capnp::POINTERS), value);
189+
}
190+
inline void Record::Builder::setStrings(::kj::ArrayPtr<const ::capnp::Text::Reader> value) {
191+
::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text>>::set(
192+
_builder.getPointerField(1 * ::capnp::POINTERS), value);
193+
}
194+
inline ::capnp::List< ::capnp::Text>::Builder Record::Builder::initStrings(unsigned int size) {
195+
return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text>>::init(
196+
_builder.getPointerField(1 * ::capnp::POINTERS), size);
197+
}
198+
inline void Record::Builder::adoptStrings(
199+
::capnp::Orphan< ::capnp::List< ::capnp::Text>>&& value) {
200+
::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text>>::adopt(
201+
_builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value));
202+
}
203+
inline ::capnp::Orphan< ::capnp::List< ::capnp::Text>> Record::Builder::disownStrings() {
204+
return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text>>::disown(
205+
_builder.getPointerField(1 * ::capnp::POINTERS));
206+
}
207+
208+
} // namespace
209+
210+
#endif // CAPNP_INCLUDED_ead5e4c3b2579756_

test.capnp

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@0xead5e4c3b2579756;
2+
3+
$import "/capnp/c++.capnp".namespace("capnp_test");
4+
5+
struct Record {
6+
ids @0 :List(Int64);
7+
strings @1 :List(Text);
8+
}

0 commit comments

Comments
 (0)