Skip to content

Commit 7db8dba

Browse files
authored
Merge pull request #28 from basiliscos/minor-speed-improvements
Minor speed improvements
2 parents d128f12 + 353345f commit 7db8dba

File tree

5 files changed

+75
-53
lines changed

5 files changed

+75
-53
lines changed

examples/speed_test_async_multi.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ int main(int argc, char **argv) {
5555
using next_layer_t = socket_t;
5656
using Buffer = boost::asio::streambuf;
5757
using Iterator = typename r::to_iterator<Buffer>::iterator_t;
58-
using policy_t = r::parsing_policy::drop_result;
59-
//using policy_t = r::parsing_policy::keep_result;
58+
//using policy_t = r::parsing_policy::drop_result;
59+
using policy_t = r::parsing_policy::keep_result;
6060

6161
if (argc < 2) {
6262
std::cout << "Usage : " << argv[0] << " ip:port \n";

include/bredis/impl/async_op.ipp

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,52 @@
1717

1818
namespace bredis {
1919

20-
template <typename Iterator, typename Policy> struct result_handler_t;
20+
struct base_result_visitor_t : public boost::static_visitor<std::size_t> {
21+
boost::system::error_code &error_code_;
22+
23+
base_result_visitor_t(boost::system::error_code &error_code)
24+
: error_code_{error_code} {}
25+
26+
std::size_t operator()(const not_enough_data_t &) const { std::abort(); }
27+
28+
std::size_t operator()(const protocol_error_t &value) const {
29+
error_code_ = value.code;
30+
return 0;
31+
}
32+
};
33+
34+
template <typename Iterator, typename Policy> struct result_visitor_t;
2135

2236
template <typename Iterator>
23-
struct result_handler_t<Iterator, parsing_policy::drop_result> {
37+
struct result_visitor_t<Iterator, parsing_policy::drop_result>
38+
: public base_result_visitor_t {
39+
using base_t = base_result_visitor_t;
2440
using policy_t = parsing_policy::drop_result;
2541
using positive_result_t = parse_result_mapper_t<Iterator, policy_t>;
2642

2743
std::size_t replies_count;
44+
positive_result_t &result;
2845
size_t cumulative_consumption;
2946
size_t count;
30-
positive_result_t result;
3147

32-
result_handler_t(std::size_t replies_count_)
33-
: replies_count{replies_count_},
34-
cumulative_consumption{0}, count{0}, result{0} {}
48+
static positive_result_t construct() { return positive_result_t{0}; }
49+
50+
result_visitor_t(boost::system::error_code &error_code,
51+
std::size_t replies_count_, positive_result_t &result_)
52+
: base_t{error_code}, replies_count{replies_count_}, result{result_},
53+
cumulative_consumption{0}, count{0} {}
3554

3655
void init() {
3756
// NO-OP;
3857
}
3958

40-
bool on_result(positive_result_t &&parse_result) {
59+
using base_t::operator();
60+
61+
size_t operator()(const positive_result_t &parse_result) {
4162
++count;
4263
cumulative_consumption += parse_result.consumed;
43-
return count < replies_count;
64+
// return parse_result.consumed;
65+
return count < replies_count ? parse_result.consumed : 0;
4466
}
4567

4668
void complete_result() {
@@ -49,26 +71,34 @@ struct result_handler_t<Iterator, parsing_policy::drop_result> {
4971
};
5072

5173
template <typename Iterator>
52-
struct result_handler_t<Iterator, parsing_policy::keep_result> {
74+
struct result_visitor_t<Iterator, parsing_policy::keep_result>
75+
: public base_result_visitor_t {
76+
using base_t = base_result_visitor_t;
5377
using policy_t = parsing_policy::keep_result;
5478
using positive_result_t = parse_result_mapper_t<Iterator, policy_t>;
5579

5680
std::size_t replies_count;
81+
positive_result_t &result;
5782
size_t cumulative_consumption;
5883
size_t count;
59-
positive_result_t result;
6084
markers::array_holder_t<Iterator> tmp_results;
6185

62-
result_handler_t(std::size_t replies_count_)
63-
: replies_count{replies_count_}, cumulative_consumption{0}, count{0} {}
86+
static positive_result_t construct() { return positive_result_t{}; }
87+
88+
result_visitor_t(boost::system::error_code &error_code,
89+
std::size_t replies_count_, positive_result_t &result_)
90+
: base_t{error_code}, replies_count{replies_count_}, result{result_},
91+
cumulative_consumption{0}, count{0} {}
6492

6593
void init() { tmp_results.elements.reserve(replies_count); }
6694

67-
bool on_result(positive_result_t &&parse_result) {
95+
using base_t::operator();
96+
97+
size_t operator()(const positive_result_t &parse_result) {
6898
tmp_results.elements.emplace_back(std::move(parse_result.result));
6999
++count;
70100
cumulative_consumption += parse_result.consumed;
71-
return count < replies_count;
101+
return count < replies_count ? parse_result.consumed : 0;
72102
}
73103

74104
void complete_result() {
@@ -89,45 +119,36 @@ template <typename DynamicBuffer, typename Policy> struct async_read_op_impl {
89119
async_read_op_impl(DynamicBuffer &rx_buff, std::size_t replies_count)
90120
: rx_buff_{rx_buff}, replies_count_{replies_count} {}
91121
using Iterator = typename to_iterator<DynamicBuffer>::iterator_t;
92-
using ResultHandler = result_handler_t<Iterator, Policy>;
122+
using ResultVisitor = result_visitor_t<Iterator, Policy>;
93123
using positive_result_t = parse_result_mapper_t<Iterator, Policy>;
94124

95125
positive_result_t op(boost::system::error_code &error_code,
96126
std::size_t /*bytes_transferred*/) {
97127

98-
ResultHandler result_handler(replies_count_);
128+
auto result = ResultVisitor::construct();
99129

100130
if (!error_code) {
101131
auto const_buff = rx_buff_.data();
102132
auto begin = Iterator::begin(const_buff);
103133
auto end = Iterator::end(const_buff);
104134

105-
result_handler.init();
135+
ResultVisitor visitor(error_code, replies_count_, result);
136+
visitor.init();
106137

107-
bool continue_parsing;
138+
std::size_t consumed{0};
108139
do {
109-
using boost::get;
140+
begin += consumed;
110141
auto parse_result =
111142
Protocol::parse<Iterator, Policy>(begin, end);
112-
auto *parse_error = boost::get<protocol_error_t>(&parse_result);
113-
if (parse_error) {
114-
error_code = parse_error->code;
115-
continue_parsing = false;
116-
} else {
117-
auto &positive_result =
118-
get<positive_result_t>(parse_result);
119-
begin += positive_result.consumed;
120-
continue_parsing =
121-
result_handler.on_result(std::move(positive_result));
122-
}
123-
} while (continue_parsing);
143+
consumed = boost::apply_visitor(visitor, parse_result);
144+
} while (consumed);
124145

125146
/* check again, as protocol error might be met */
126147
if (!error_code) {
127-
result_handler.complete_result();
148+
visitor.complete_result();
128149
}
129150
}
130-
return result_handler.result;
151+
return result;
131152
}
132153
};
133154

include/bredis/impl/common.ipp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,22 @@ template <typename Iterator> class MatchResult {
7474
}
7575
};
7676

77-
class command_serializer_visitor : public boost::static_visitor<std::string> {
77+
class command_serializer_visitor : public boost::static_visitor<void> {
78+
private:
79+
std::ostream &out_;
80+
7881
public:
79-
std::string operator()(const single_command_t &value) const {
80-
std::stringstream out;
81-
out.imbue(std::locale::classic());
82-
Protocol::serialize(out, value);
83-
return out.str();
82+
command_serializer_visitor(std::ostream &out) : out_{out} {}
83+
void operator()(const single_command_t &value) const {
84+
out_.imbue(std::locale::classic());
85+
Protocol::serialize(out_, value);
8486
}
8587

86-
std::string operator()(const command_container_t &value) const {
87-
std::stringstream out;
88-
out.imbue(std::locale::classic());
88+
void operator()(const command_container_t &value) const {
89+
out_.imbue(std::locale::classic());
8990
for (const auto &cmd : value) {
90-
Protocol::serialize(out, cmd);
91+
Protocol::serialize(out_, cmd);
9192
}
92-
return out.str();
9393
}
9494
};
9595

include/bredis/impl/connection.ipp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ Connection<NextLayer>::async_write(DynamicBuffer &tx_buff,
3232
typename asio::handler_type<WriteCallback, Signature>::type;
3333

3434
std::ostream os(&tx_buff);
35-
auto string = boost::apply_visitor(command_serializer_visitor(), command);
36-
os.write(string.c_str(), string.size());
35+
boost::apply_visitor(command_serializer_visitor(os), command);
3736

3837
real_handler_t handler(std::forward<WriteCallback>(write_callback));
3938
return async_write(stream_, tx_buff, handler);
@@ -72,9 +71,10 @@ template <typename NextLayer>
7271
void Connection<NextLayer>::write(const command_wrapper_t &command,
7372
boost::system::error_code &ec) {
7473
namespace asio = boost::asio;
75-
auto str = boost::apply_visitor(command_serializer_visitor(), command);
76-
auto const output_buf = asio::buffer(str.c_str(), str.size());
77-
asio::write(stream_, output_buf, ec);
74+
asio::streambuf tx_buff;
75+
std::ostream os(&tx_buff);
76+
boost::apply_visitor(command_serializer_visitor(os), command);
77+
asio::write(stream_, tx_buff, ec);
7878
}
7979

8080
template <typename NextLayer>

t/11-multi-ping.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ TEST_CASE("ping", "[connection]") {
3737

3838
std::chrono::nanoseconds sleep_delay(1);
3939

40-
auto count = 1000;
40+
size_t count = 1000;
4141
r::single_command_t ping_cmd("ping");
4242
r::command_container_t ping_cmds_container;
43-
for (auto i = 0; i < count; ++i) {
43+
ping_cmds_container.reserve(count);
44+
for (size_t i = 0; i < count; ++i) {
4445
ping_cmds_container.push_back(ping_cmd);
4546
}
4647
r::command_wrapper_t cmd(ping_cmds_container);

0 commit comments

Comments
 (0)