diff --git a/examples/echo_server/echo_server.cpp b/examples/echo_server/echo_server.cpp index 616b8c28880ecc4bb010a47e6308ae1f20e8ae8e..3595bed18fb9af6c60760a077ec158820d4737af 100644 --- a/examples/echo_server/echo_server.cpp +++ b/examples/echo_server/echo_server.cpp @@ -8,7 +8,7 @@ //#define ASCS_SYNC_DISPATCH //do not open this feature, see below for more details #define ASCS_DISPATCH_BATCH_MSG #define ASCS_ENHANCED_STABILITY -#define ASCS_FULL_STATISTIC //full statistic will slightly impact efficiency +//#define ASCS_FULL_STATISTIC //full statistic will slightly impact efficiency #define ASCS_USE_STEADY_TIMER #define ASCS_ALIGNED_TIMER #define ASCS_AVOID_AUTO_STOP_SERVICE diff --git a/include/ascs/base.h b/include/ascs/base.h index 76a365dd28742b2c9148fcc15572a28c33574f91..a46d50350e9d7b015fd8b8e75f12b8a70be9f349 100644 --- a/include/ascs/base.h +++ b/include/ascs/base.h @@ -488,6 +488,14 @@ size_t get_size_in_byte(const _Can& __can) return size_in_byte; } +template +size_t get_size_in_byte(const _Can& __can, size_t& size) +{ + auto size_in_byte = size = 0; + do_something_to_all(__can, [&size_in_byte, &size](typename _Can::const_reference item) {size_in_byte += item.size(); ++size;}); + return size_in_byte; +} + //member functions, used to do something to any member container(except map and multimap) optionally with any member mutex #define DO_SOMETHING_TO_ALL_MUTEX(CAN, MUTEX) DO_SOMETHING_TO_ALL_MUTEX_NAME(do_something_to_all, CAN, MUTEX) #define DO_SOMETHING_TO_ALL(CAN) DO_SOMETHING_TO_ALL_NAME(do_something_to_all, CAN) diff --git a/include/ascs/socket.h b/include/ascs/socket.h index bc53f1f7d4622e414372c8596708bcacffed3b06..668e73268083e571589c7562e14275cc7f074bff 100644 --- a/include/ascs/socket.h +++ b/include/ascs/socket.h @@ -370,8 +370,9 @@ protected: bool handle_msg() { - auto size_in_byte = ascs::get_size_in_byte(temp_msg_can); - stat.recv_msg_sum += temp_msg_can.size(); //this can have linear complexity in old gcc or Cygwin and Mingw64, please note. + size_t size = 0; + auto size_in_byte = ascs::get_size_in_byte(temp_msg_can, size); + stat.recv_msg_sum += size; stat.recv_byte_sum += size_in_byte; #ifdef ASCS_SYNC_RECV std::unique_lock lock(sync_recv_mutex); diff --git a/include/ascs/tcp/socket.h b/include/ascs/tcp/socket.h index a60a8fd10e294eace9857b2b4cebca301b3ef844..2167cc37d2b023823de0eb6db939af74092cdbba 100644 --- a/include/ascs/tcp/socket.h +++ b/include/ascs/tcp/socket.h @@ -300,18 +300,16 @@ private: #else send_msg_buffer.move_items_out(asio::detail::default_max_transfer_size, last_send_msg); #endif - std::vector bufs; - bufs.reserve(last_send_msg.size()); - for (auto iter = std::begin(last_send_msg); iter != std::end(last_send_msg); ++iter) - { - stat.send_delay_sum += end_time - iter->begin_time; - bufs.emplace_back(iter->data(), iter->size()); - } + send_bufs.clear(); //this buffer will not be refreshed according to last_send_msg timely + ascs::do_something_to_all(last_send_msg, [this, &end_time](typename super::in_msg& item) { + this->stat.send_delay_sum += end_time - item.begin_time; + this->send_bufs.emplace_back(item.data(), item.size()); + }); - if ((sending = !bufs.empty())) + if ((sending = !send_bufs.empty())) { last_send_msg.front().restart(); - asio::async_write(this->next_layer(), bufs, make_strand_handler(strand, + asio::async_write(this->next_layer(), send_bufs, make_strand_handler(strand, this->make_handler_error_size([this](const asio::error_code& ec, size_t bytes_transferred) {this->send_handler(ec, bytes_transferred);}))); return true; } @@ -327,7 +325,7 @@ private: stat.send_byte_sum += bytes_transferred; stat.send_time_sum += statistic::now() - last_send_msg.front().begin_time; - stat.send_msg_sum += last_send_msg.size(); + stat.send_msg_sum += send_bufs.size(); #ifdef ASCS_SYNC_SEND ascs::do_something_to_all(last_send_msg, [](typename super::in_msg& item) {if (item.p) {item.p->set_value(sync_call_result::SUCCESS);}}); #endif @@ -391,6 +389,7 @@ private: std::shared_ptr> unpacker_; typename super::in_container_type last_send_msg; + std::vector send_bufs; //just to reduce memory allocation and keep the size of sending items (linear complexity, it's very important) asio::io_context::strand strand; };