From ada3513d36258e8ea482072bd2e07282d95b46a2 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 20 Mar 2015 10:56:53 +0200 Subject: [PATCH] transport: Use std::vector for response building Optimize CQL response building by switching from std::stringstream to std::vector. Improves single core cassandra-stress write throughput by ~8%. Before: [penberg@nero urchin]$ taskset -c 1 ./build/release/seastar --data data --smp 1 [penberg@nero apache-cassandra-2.1.0]$ ./tools/bin/cassandra-stress write -mode cql3 simplenative prepared -rate threads=32 Results: op rate : 73538 partition rate : 73538 row rate : 73538 latency mean : 0.4 latency median : 0.4 latency 95th percentile : 0.7 latency 99th percentile : 1.1 latency 99.9th percentile : 4.9 latency max : 147.8 Total operation time : 00:00:30 END After: [penberg@nero urchin]$ taskset -c 1 ./build/release/seastar --data data --smp 1 [penberg@nero apache-cassandra-2.1.0]$ ./tools/bin/cassandra-stress write -mode cql3 simplenative prepared -rate threads=32 Results: op rate : 79447 partition rate : 79447 row rate : 79447 latency mean : 0.4 latency median : 0.3 latency 95th percentile : 0.7 latency 99th percentile : 1.0 latency 99.9th percentile : 4.2 latency max : 87.1 Total operation time : 00:00:30 END Signed-off-by: Pekka Enberg --- transport/server.cc | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/transport/server.cc b/transport/server.cc index e498ce3621..448e0ee24b 100644 --- a/transport/server.cc +++ b/transport/server.cc @@ -196,7 +196,7 @@ private: class cql_server::response { int16_t _stream; cql_binary_opcode _opcode; - std::stringstream _body; + std::vector _body; public: response(int16_t stream, cql_binary_opcode opcode) : _stream{stream} @@ -813,7 +813,7 @@ bytes_opt cql_server::connection::read_value(temporary_buffer& buf) { scattered_message cql_server::response::make_message(uint8_t version) { scattered_message msg; - sstring body = _body.str(); + sstring body{_body.data(), _body.size()}; sstring frame = make_frame(version, body.size()); msg.append(std::move(frame)); msg.append(std::move(body)); @@ -853,33 +853,36 @@ sstring cql_server::response::make_frame(uint8_t version, size_t length) void cql_server::response::write_int(int32_t n) { auto u = htonl(n); - _body.write(reinterpret_cast(&u), sizeof(u)); + auto *s = reinterpret_cast(&u); + _body.insert(_body.end(), s, s+sizeof(u)); } void cql_server::response::write_long(int64_t n) { auto u = htonq(n); - _body.write(reinterpret_cast(&u), sizeof(u)); + auto *s = reinterpret_cast(&u); + _body.insert(_body.end(), s, s+sizeof(u)); } void cql_server::response::write_short(int16_t n) { auto u = htons(n); - _body.write(reinterpret_cast(&u), sizeof(u)); + auto *s = reinterpret_cast(&u); + _body.insert(_body.end(), s, s+sizeof(u)); } void cql_server::response::write_string(const sstring& s) { assert(s.size() < std::numeric_limits::max()); write_short(s.size()); - _body << s; + _body.insert(_body.end(), s.begin(), s.end()); } void cql_server::response::write_long_string(const sstring& s) { assert(s.size() < std::numeric_limits::max()); write_int(s.size()); - _body << s; + _body.insert(_body.end(), s.begin(), s.end()); } void cql_server::response::write_uuid(utils::UUID uuid) @@ -901,14 +904,14 @@ void cql_server::response::write_bytes(bytes b) { assert(b.size() < std::numeric_limits::max()); write_int(b.size()); - _body.write(b.begin(), b.size()); + _body.insert(_body.end(), b.begin(), b.end()); } void cql_server::response::write_short_bytes(bytes b) { assert(b.size() < std::numeric_limits::max()); write_short(b.size()); - _body.write(b.begin(), b.size()); + _body.insert(_body.end(), b.begin(), b.end()); } void cql_server::response::write_option(std::pair opt) @@ -971,7 +974,7 @@ void cql_server::response::write_value(bytes_opt value) } write_int(value->size()); - _body << *value; + _body.insert(_body.end(), *value->begin(), *value->end()); } class type_codec {