diff options
author | Evan Martin <martine@danga.com> | 2012-09-14 22:05:13 (GMT) |
---|---|---|
committer | Evan Martin <martine@danga.com> | 2012-09-14 22:05:13 (GMT) |
commit | d95fcb0cdc816e2585ce9a65676320d71af78c7f (patch) | |
tree | 19f7f936ddc0de1a6c0a9c3a0920a3d5e66d2d5b | |
parent | a79de825547f41b83ee60c359397b99045f01999 (diff) | |
parent | 48143c9b07eca30c99d47cadf3c0ae111b369f1b (diff) | |
download | Ninja-d95fcb0cdc816e2585ce9a65676320d71af78c7f.zip Ninja-d95fcb0cdc816e2585ce9a65676320d71af78c7f.tar.gz Ninja-d95fcb0cdc816e2585ce9a65676320d71af78c7f.tar.bz2 |
Merge pull request #416 from nico/slide
Change rate measurement code.
-rw-r--r-- | src/build.cc | 24 | ||||
-rw-r--r-- | src/build.h | 58 | ||||
-rw-r--r-- | src/metrics.h | 9 |
3 files changed, 53 insertions, 38 deletions
diff --git a/src/build.cc b/src/build.cc index e1aaad1..5a0c3b3 100644 --- a/src/build.cc +++ b/src/build.cc @@ -42,8 +42,7 @@ BuildStatus::BuildStatus(const BuildConfig& config) start_time_millis_(GetTimeMillis()), started_edges_(0), finished_edges_(0), total_edges_(0), have_blank_line_(true), progress_status_format_(NULL), - overall_rate_(), current_rate_(), - current_rate_average_count_(config.parallelism) { + overall_rate_(), current_rate_(config.parallelism) { #ifndef _WIN32 const char* term = getenv("TERM"); smart_terminal_ = isatty(1) && term && string(term) != "dumb"; @@ -136,7 +135,8 @@ void BuildStatus::BuildFinished() { printf("\n"); } -string BuildStatus::FormatProgressStatus(const char* progress_status_format) const { +string BuildStatus::FormatProgressStatus( + const char* progress_status_format) const { string out; char buf[32]; for (const char* s = progress_status_format; *s != '\0'; ++s) { @@ -177,30 +177,24 @@ string BuildStatus::FormatProgressStatus(const char* progress_status_format) con out += buf; break; - // Overall finished edges per second. + // Overall finished edges per second. case 'o': - overall_rate_.UpdateRate(finished_edges_, finished_edges_); + overall_rate_.UpdateRate(finished_edges_); overall_rate_.snprinfRate(buf, "%.1f"); out += buf; break; - // Current rate, average over the last '-j' jobs. + // Current rate, average over the last '-j' jobs. case 'c': - // TODO use sliding window? - if (finished_edges_ > current_rate_.last_update() && - finished_edges_ - current_rate_.last_update() == current_rate_average_count_) { - current_rate_.UpdateRate(current_rate_average_count_, finished_edges_); - current_rate_.Restart(); - } - current_rate_.snprinfRate(buf, "%.0f"); + current_rate_.UpdateRate(finished_edges_); + current_rate_.snprinfRate(buf, "%.1f"); out += buf; break; - default: { + default: Fatal("unknown placeholder '%%%c' in $NINJA_STATUS", *s); return ""; } - } } else { out.push_back(*s); } diff --git a/src/build.h b/src/build.h index 3e7a144..0902a4c 100644 --- a/src/build.h +++ b/src/build.h @@ -201,37 +201,59 @@ struct BuildStatus { const char* progress_status_format_; struct RateInfo { - RateInfo() : last_update_(0), rate_(-1) {} - - double rate() const { return rate_; } - int last_update() const { return last_update_; } - void Restart() { return stopwatch_.Restart(); } - - double UpdateRate(int edges, int update_hint) { - if (update_hint != last_update_) { - rate_ = edges / stopwatch_.Elapsed() + 0.5; - last_update_ = update_hint; - } - return rate_; + RateInfo() : rate_(-1) {} + + void Restart() { stopwatch_.Restart(); } + + void UpdateRate(int edges) { + if (edges && stopwatch_.Elapsed()) + rate_ = edges / stopwatch_.Elapsed(); + } + + template<class T> + void snprinfRate(T buf, const char* format) { + if (rate_ == -1) snprintf(buf, sizeof(buf), "?"); + else snprintf(buf, sizeof(buf), format, rate_); + } + + private: + Stopwatch stopwatch_; + double rate_; + }; + + struct SlidingRateInfo { + SlidingRateInfo(int n) : N(n), last_update_(-1), rate_(-1) {} + + void Restart() { stopwatch_.Restart(); } + + void UpdateRate(int update_hint) { + if (update_hint == last_update_) + return; + last_update_ = update_hint; + + if (times_.size() == N) + times_.pop(); + times_.push(stopwatch_.Elapsed()); + if (times_.back() != times_.front()) + rate_ = times_.size() / (times_.back() - times_.front()); } template<class T> void snprinfRate(T buf, const char* format) { - if (rate_ == -1) - snprintf(buf, sizeof(buf), "?"); - else - snprintf(buf, sizeof(buf), format, rate_); + if (rate_ == -1) snprintf(buf, sizeof(buf), "?"); + else snprintf(buf, sizeof(buf), format, rate_); } private: + const size_t N; + std::queue<double> times_; Stopwatch stopwatch_; int last_update_; double rate_; }; mutable RateInfo overall_rate_; - mutable RateInfo current_rate_; - const int current_rate_average_count_; + mutable SlidingRateInfo current_rate_; #ifdef _WIN32 void* console_; diff --git a/src/metrics.h b/src/metrics.h index f5ac0de..a4ef9f7 100644 --- a/src/metrics.h +++ b/src/metrics.h @@ -59,19 +59,18 @@ private: }; /// Get the current time as relative to some epoch. -/// Epoch varies between platforms; only useful for measuring elapsed -/// time. +/// Epoch varies between platforms; only useful for measuring elapsed time. int64_t GetTimeMillis(); -/// A simple stopwatch which retruns the time -// in seconds since Restart() was called +/// A simple stopwatch which returns the time +/// in seconds since Restart() was called. class Stopwatch { public: Stopwatch() : started_(0) {} - /// Seconds since Restart() call + /// Seconds since Restart() call. double Elapsed() const { return 1e-6 * static_cast<double>(Now() - started_); } void Restart() { started_ = Now(); } |