Skip to content

Commit 9ff7c12

Browse files
committed
Optimizations.
1 parent 6c13b48 commit 9ff7c12

File tree

2 files changed

+47
-45
lines changed

2 files changed

+47
-45
lines changed

source/base/threading/asio_event_dispatcher.cc

+36-28
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,23 @@
3030

3131
namespace base {
3232

33+
namespace {
34+
35+
const size_t kReservedSizeForTimersMap = 100;
36+
const float kLoadFactorForTimersMap = 0.5;
37+
38+
} // namespace
39+
3340
//--------------------------------------------------------------------------------------------------
3441
AsioEventDispatcher::AsioEventDispatcher(QObject* parent)
3542
: QAbstractEventDispatcher(parent),
3643
work_guard_(asio::make_work_guard(io_context_)),
37-
timer_(io_context_)
44+
high_resolution_timer_(io_context_)
3845
{
3946
LOG(LS_INFO) << "Ctor";
47+
48+
timers_.reserve(kReservedSizeForTimersMap);
49+
timers_.max_load_factor(kLoadFactorForTimersMap);
4050
}
4151

4252
//--------------------------------------------------------------------------------------------------
@@ -107,8 +117,8 @@ void AsioEventDispatcher::unregisterSocketNotifier(QSocketNotifier* /* notifier
107117
void AsioEventDispatcher::registerTimer(
108118
int id, int interval, Qt::TimerType type, QObject* object)
109119
{
110-
TimePoint start_time = Clock::now();
111-
TimePoint expire_time = start_time + Milliseconds(interval);
120+
const TimePoint start_time = Clock::now();
121+
const TimePoint expire_time = start_time + Milliseconds(interval);
112122

113123
timers_.emplace(
114124
std::make_pair(id, TimerData(id, interval, type, object, start_time, expire_time)));
@@ -161,7 +171,7 @@ QList<QAbstractEventDispatcher::TimerInfo> AsioEventDispatcher::registeredTimers
161171
for (auto it = timers_.cbegin(), it_end = timers_.cend(); it != it_end; ++it)
162172
{
163173
if (it->second.object == object)
164-
list.append({ it->second.id, it->second.interval, it->second.type });
174+
list.append({ it->second.timer_id, it->second.interval, it->second.type });
165175
}
166176

167177
return list;
@@ -233,8 +243,8 @@ void AsioEventDispatcher::unregisterEventNotifier(QWinEventNotifier* notifier)
233243
//--------------------------------------------------------------------------------------------------
234244
void AsioEventDispatcher::wakeUp()
235245
{
236-
// Send an empty lambda so that call run_one inside method processEvents completes.
237-
asio::post(io_context_, []{});
246+
// To stop run_one inside method processEvents completes.
247+
io_context_.stop();
238248
}
239249

240250
//--------------------------------------------------------------------------------------------------
@@ -296,34 +306,32 @@ void AsioEventDispatcher::asyncWaitForNextTimer()
296306
return lhs.second.expire_time < rhs.second.expire_time;
297307
});
298308

299-
// Start waiting for the timer.
300-
timer_.expires_at(next_expire_timer->second.expire_time);
301-
timer_.async_wait(std::bind(
302-
&AsioEventDispatcher::onTimerEvent, this, std::placeholders::_1, next_expire_timer->second.id));
303-
}
309+
const int next_timer_id = next_expire_timer->second.timer_id;
304310

305-
//--------------------------------------------------------------------------------------------------
306-
void AsioEventDispatcher::onTimerEvent(const std::error_code& error_code, int id)
307-
{
308-
if (error_code || interrupted_.load(std::memory_order_relaxed))
309-
return;
311+
// Start waiting for the timer.
312+
high_resolution_timer_.expires_at(next_expire_timer->second.expire_time);
313+
high_resolution_timer_.async_wait([this, next_timer_id](const std::error_code& error_code)
314+
{
315+
if (error_code || interrupted_.load(std::memory_order_relaxed))
316+
return;
310317

311-
auto it = timers_.find(id);
312-
if (it == timers_.end())
313-
return;
318+
auto it = timers_.find(next_timer_id);
319+
if (it == timers_.end())
320+
return;
314321

315-
QCoreApplication::sendEvent(it->second.object, new QTimerEvent(id));
322+
QCoreApplication::sendEvent(it->second.object, new QTimerEvent(next_timer_id));
316323

317-
// When calling method sendEvent the timer may have been deleted, so we look for it again.
318-
it = timers_.find(id);
319-
if (it == timers_.end())
320-
return;
324+
// When calling method sendEvent the timer may have been deleted, so we look for it again.
325+
it = timers_.find(next_timer_id);
326+
if (it == timers_.end())
327+
return;
321328

322-
TimerData& timer = it->second;
323-
timer.start_time = Clock::now();
324-
timer.expire_time = timer.start_time + Milliseconds(timer.interval);
329+
TimerData& timer = it->second;
330+
timer.start_time = Clock::now();
331+
timer.expire_time = timer.start_time + Milliseconds(timer.interval);
325332

326-
asyncWaitForNextTimer();
333+
asyncWaitForNextTimer();
334+
});
327335
}
328336

329337
} // namespace base

source/base/threading/asio_event_dispatcher.h

+11-17
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,7 @@ class AsioEventDispatcher final : public QAbstractEventDispatcher
7070

7171
struct TimerData
7272
{
73-
TimerData(int id, int interval, Qt::TimerType type, QObject* object,
74-
TimePoint start_time, TimePoint expire_time)
75-
: id(id),
76-
interval(interval),
77-
type(type),
78-
object(object),
79-
start_time(start_time),
80-
expire_time(expire_time)
81-
{
82-
// Nothing
83-
}
84-
85-
int id;
73+
int timer_id;
8674
int interval;
8775
Qt::TimerType type;
8876
QObject* object;
@@ -103,15 +91,21 @@ class AsioEventDispatcher final : public QAbstractEventDispatcher
10391
std::list<EventData> events_;
10492
#endif // defined(Q_OS_WIN)
10593

106-
TimePoint calculateNextRunTime();
10794
void asyncWaitForNextTimer();
108-
void onTimerEvent(const std::error_code& error_code, int id);
95+
96+
struct FastHash
97+
{
98+
size_t operator()(int timer_id) const noexcept
99+
{
100+
return static_cast<size_t>(timer_id);
101+
}
102+
};
109103

110104
asio::io_context io_context_;
111105
asio::executor_work_guard<asio::io_context::executor_type> work_guard_;
112106
std::atomic_bool interrupted_ { false };
113-
std::unordered_map<int, TimerData> timers_;
114-
asio::high_resolution_timer timer_;
107+
std::unordered_map<int, TimerData, FastHash> timers_;
108+
asio::high_resolution_timer high_resolution_timer_;
115109

116110
DISALLOW_COPY_AND_ASSIGN(AsioEventDispatcher);
117111
};

0 commit comments

Comments
 (0)