diff options
author | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-21 06:11:11 +0000 |
---|---|---|
committer | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-21 06:11:11 +0000 |
commit | 0bb07852c6769a990a585a740613014520503dfe (patch) | |
tree | e9d580bd4286e428f66aba5c64e83fab475e4f5a /base/message_loop.cc | |
parent | f6f7e9f58f9d8c6b676ae26f462a4bb9f079bdcd (diff) | |
download | chromium_src-0bb07852c6769a990a585a740613014520503dfe.zip chromium_src-0bb07852c6769a990a585a740613014520503dfe.tar.gz chromium_src-0bb07852c6769a990a585a740613014520503dfe.tar.bz2 |
Test of performance value of reducing calls to Now().
I'll revert asap, once the perf bots have kicked off.
TBR=mbelshe
Review URL: http://codereview.chromium.org/3936003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63332 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/message_loop.cc')
-rw-r--r-- | base/message_loop.cc | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/base/message_loop.cc b/base/message_loop.cc index 8f6c997b..50bd44c 100644 --- a/base/message_loop.cc +++ b/base/message_loop.cc @@ -494,6 +494,11 @@ bool MessageLoop::DeletePendingTasks() { delete task; } did_work |= !delayed_work_queue_.empty(); + while (!ripe_work_queue_.empty()) { + Task* task = ripe_work_queue_.front().task; + delayed_work_queue_.pop(); + delete task; + } while (!delayed_work_queue_.empty()) { Task* task = delayed_work_queue_.top().task; delayed_work_queue_.pop(); @@ -520,7 +525,8 @@ bool MessageLoop::DoWork() { if (!pending_task.delayed_run_time.is_null()) { AddToDelayedWorkQueue(pending_task); // If we changed the topmost task, then it is time to re-schedule. - if (delayed_work_queue_.top().task == pending_task.task) + if (ripe_work_queue_.empty() && + delayed_work_queue_.top().task == pending_task.task) pump_->ScheduleDelayedWork(pending_task.delayed_run_time); } else { if (DeferOrRunPendingTask(pending_task)) @@ -534,21 +540,46 @@ bool MessageLoop::DoWork() { } bool MessageLoop::DoDelayedWork(Time* next_delayed_work_time) { - if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) { + if (!nestable_tasks_allowed_ || + (delayed_work_queue_.empty() && ripe_work_queue_.empty())) { *next_delayed_work_time = 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 will 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() once, and then move all ready-to-run tasks + // (i.e., tasks that are "ripe") into ripe_work_queue_. 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. + + if (ripe_work_queue_.empty()) { + base::Time now(Time::Now()); + + if (delayed_work_queue_.top().delayed_run_time > now) { + *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time; + return false; + } + + do { + ripe_work_queue_.push(delayed_work_queue_.top()); + delayed_work_queue_.pop(); + } while (!delayed_work_queue_.empty() && + (delayed_work_queue_.top().delayed_run_time <= now)); + /* DHISTOGRAM_COUNTS("Chrome.RipeSize", + static_cast<int>(ripe_work_queue_.size())); + */ } - PendingTask pending_task = delayed_work_queue_.top(); - delayed_work_queue_.pop(); + PendingTask pending_task = ripe_work_queue_.front(); + ripe_work_queue_.pop(); - if (!delayed_work_queue_.empty()) + if (!ripe_work_queue_.empty()) + *next_delayed_work_time = ripe_work_queue_.front().delayed_run_time; + else if (!delayed_work_queue_.empty()) *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time; + else + *next_delayed_work_time = Time(); return DeferOrRunPendingTask(pending_task); } |