From a8f7d3d010cb872f92132c7c2482c6188829346d Mon Sep 17 00:00:00 2001 From: "jar@chromium.org" Date: Thu, 4 Nov 2010 23:23:42 +0000 Subject: Try to improve message_loop efficiency when backlogged The call to Now() uses a lock to handle roll over events, and that might make the call more expensive in some scenarios. Reduce the number of times we need to call Time::Now() when processing timer events by processing all (fully ripe, and ready to run) events with only one call to Now(). This should make the queue run faster as we fall further behind. I was hoping to see some perf improvement, but I think this will only have an impact when we are overloaded, which problably doesn't happen often on the bots. I did some local histogramming, and I do see cases where we get away with processing several (2-3) events with one call to Now(), but that is apparently not enough to move the needle on the perf bots. r=darin Review URL: http://codereview.chromium.org/4247003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65131 0039d316-1c4b-4281-b951-d872f2087c98 --- base/message_loop.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'base/message_loop.cc') diff --git a/base/message_loop.cc b/base/message_loop.cc index b20e6b6..b860fd8 100644 --- a/base/message_loop.cc +++ b/base/message_loop.cc @@ -542,13 +542,23 @@ bool MessageLoop::DoWork() { bool MessageLoop::DoDelayedWork(base::Time* next_delayed_work_time) { if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) { - *next_delayed_work_time = base::Time(); + recent_time_ = *next_delayed_work_time = base::Time(); return false; } - if (delayed_work_queue_.top().delayed_run_time > Time::Now()) { - *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time; - return false; + // When we "fall behind," there may be a lot of tasks in the delayed work + // queue that are ready to run. To increase efficiency when we fall behind, + // we will only call Time::Now() intermittently, and then process all tasks + // that are ready to run before calling it again. As a result, the more we + // fall behind (and have a lot of ready-to-run delayed tasks), the more + // efficient we'll be at handling the tasks. + base::Time next_run_time = delayed_work_queue_.top().delayed_run_time; + if (next_run_time > recent_time_) { + recent_time_ = base::Time::Now(); // Get a better view of Now(). + if (next_run_time > recent_time_) { + *next_delayed_work_time = next_run_time; + return false; + } } PendingTask pending_task = delayed_work_queue_.top(); -- cgit v1.1