| OLD | NEW |
| 1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Histogram is an object that aggregates statistics, and can summarize them in | 5 // Histogram is an object that aggregates statistics, and can summarize them in |
| 6 // various forms, including ASCII graphical, HTML, and numerically (as a | 6 // various forms, including ASCII graphical, HTML, and numerically (as a |
| 7 // vector of numbers corresponding to each of the aggregating buckets). | 7 // vector of numbers corresponding to each of the aggregating buckets). |
| 8 // See header file for details and examples. | 8 // See header file for details and examples. |
| 9 | 9 |
| 10 #include "base/histogram.h" | 10 #include "base/histogram.h" |
| 11 | 11 |
| 12 #include <math.h> | 12 #include <math.h> |
| 13 #include <string> | 13 #include <string> |
| 14 | 14 |
| 15 #include "base/lock.h" | 15 #include "base/lock.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/pickle.h" | 17 #include "base/pickle.h" |
| 18 #include "base/string_util.h" | 18 #include "base/stringprintf.h" |
| 19 | 19 |
| 20 using base::TimeDelta; | 20 using base::TimeDelta; |
| 21 | 21 |
| 22 typedef Histogram::Count Count; | 22 typedef Histogram::Count Count; |
| 23 | 23 |
| 24 scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name, | 24 scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name, |
| 25 Sample minimum, Sample maximum, size_t bucket_count, Flags flags) { | 25 Sample minimum, Sample maximum, size_t bucket_count, Flags flags) { |
| 26 scoped_refptr<Histogram> histogram(NULL); | 26 scoped_refptr<Histogram> histogram(NULL); |
| 27 | 27 |
| 28 // Defensive code. | 28 // Defensive code. |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 double current_size = GetBucketSize(snapshot.counts(i), i); | 333 double current_size = GetBucketSize(snapshot.counts(i), i); |
| 334 if (current_size > max) | 334 if (current_size > max) |
| 335 max = current_size; | 335 max = current_size; |
| 336 } | 336 } |
| 337 return max; | 337 return max; |
| 338 } | 338 } |
| 339 | 339 |
| 340 void Histogram::WriteAsciiHeader(const SampleSet& snapshot, | 340 void Histogram::WriteAsciiHeader(const SampleSet& snapshot, |
| 341 Count sample_count, | 341 Count sample_count, |
| 342 std::string* output) const { | 342 std::string* output) const { |
| 343 StringAppendF(output, | 343 base::StringAppendF(output, |
| 344 "Histogram: %s recorded %d samples", | 344 "Histogram: %s recorded %d samples", |
| 345 histogram_name().c_str(), | 345 histogram_name().c_str(), |
| 346 sample_count); | 346 sample_count); |
| 347 if (0 == sample_count) { | 347 if (0 == sample_count) { |
| 348 DCHECK_EQ(snapshot.sum(), 0); | 348 DCHECK_EQ(snapshot.sum(), 0); |
| 349 } else { | 349 } else { |
| 350 double average = static_cast<float>(snapshot.sum()) / sample_count; | 350 double average = static_cast<float>(snapshot.sum()) / sample_count; |
| 351 double variance = static_cast<float>(snapshot.square_sum())/sample_count | 351 double variance = static_cast<float>(snapshot.square_sum())/sample_count |
| 352 - average * average; | 352 - average * average; |
| 353 double standard_deviation = sqrt(variance); | 353 double standard_deviation = sqrt(variance); |
| 354 | 354 |
| 355 StringAppendF(output, | 355 base::StringAppendF(output, |
| 356 ", average = %.1f, standard deviation = %.1f", | 356 ", average = %.1f, standard deviation = %.1f", |
| 357 average, standard_deviation); | 357 average, standard_deviation); |
| 358 } | 358 } |
| 359 if (flags_ & ~kHexRangePrintingFlag ) | 359 if (flags_ & ~kHexRangePrintingFlag ) |
| 360 StringAppendF(output, " (flags = 0x%x)", flags_ & ~kHexRangePrintingFlag); | 360 base::StringAppendF(output, " (flags = 0x%x)", |
| 361 flags_ & ~kHexRangePrintingFlag); |
| 361 } | 362 } |
| 362 | 363 |
| 363 void Histogram::WriteAsciiBucketContext(const int64 past, | 364 void Histogram::WriteAsciiBucketContext(const int64 past, |
| 364 const Count current, | 365 const Count current, |
| 365 const int64 remaining, | 366 const int64 remaining, |
| 366 const size_t i, | 367 const size_t i, |
| 367 std::string* output) const { | 368 std::string* output) const { |
| 368 double scaled_sum = (past + current + remaining) / 100.0; | 369 double scaled_sum = (past + current + remaining) / 100.0; |
| 369 WriteAsciiBucketValue(current, scaled_sum, output); | 370 WriteAsciiBucketValue(current, scaled_sum, output); |
| 370 if (0 < i) { | 371 if (0 < i) { |
| 371 double percentage = past / scaled_sum; | 372 double percentage = past / scaled_sum; |
| 372 StringAppendF(output, " {%3.1f%%}", percentage); | 373 base::StringAppendF(output, " {%3.1f%%}", percentage); |
| 373 } | 374 } |
| 374 } | 375 } |
| 375 | 376 |
| 376 const std::string Histogram::GetAsciiBucketRange(size_t i) const { | 377 const std::string Histogram::GetAsciiBucketRange(size_t i) const { |
| 377 std::string result; | 378 std::string result; |
| 378 if (kHexRangePrintingFlag & flags_) | 379 if (kHexRangePrintingFlag & flags_) |
| 379 StringAppendF(&result, "%#x", ranges(i)); | 380 base::StringAppendF(&result, "%#x", ranges(i)); |
| 380 else | 381 else |
| 381 StringAppendF(&result, "%d", ranges(i)); | 382 base::StringAppendF(&result, "%d", ranges(i)); |
| 382 return result; | 383 return result; |
| 383 } | 384 } |
| 384 | 385 |
| 385 void Histogram::WriteAsciiBucketValue(Count current, double scaled_sum, | 386 void Histogram::WriteAsciiBucketValue(Count current, double scaled_sum, |
| 386 std::string* output) const { | 387 std::string* output) const { |
| 387 StringAppendF(output, " (%d = %3.1f%%)", current, current/scaled_sum); | 388 base::StringAppendF(output, " (%d = %3.1f%%)", current, current/scaled_sum); |
| 388 } | 389 } |
| 389 | 390 |
| 390 void Histogram::WriteAsciiBucketGraph(double current_size, double max_size, | 391 void Histogram::WriteAsciiBucketGraph(double current_size, double max_size, |
| 391 std::string* output) const { | 392 std::string* output) const { |
| 392 const int k_line_length = 72; // Maximal horizontal width of graph. | 393 const int k_line_length = 72; // Maximal horizontal width of graph. |
| 393 int x_count = static_cast<int>(k_line_length * (current_size / max_size) | 394 int x_count = static_cast<int>(k_line_length * (current_size / max_size) |
| 394 + 0.5); | 395 + 0.5); |
| 395 int x_remainder = k_line_length - x_count; | 396 int x_remainder = k_line_length - x_count; |
| 396 | 397 |
| 397 while (0 < x_count--) | 398 while (0 < x_count--) |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 output->append("<br><hr><br>"); | 848 output->append("<br><hr><br>"); |
| 848 } | 849 } |
| 849 output->append("</body></html>"); | 850 output->append("</body></html>"); |
| 850 } | 851 } |
| 851 | 852 |
| 852 // static | 853 // static |
| 853 void StatisticsRecorder::WriteGraph(const std::string& query, | 854 void StatisticsRecorder::WriteGraph(const std::string& query, |
| 854 std::string* output) { | 855 std::string* output) { |
| 855 if (!histograms_) | 856 if (!histograms_) |
| 856 return; | 857 return; |
| 857 if (query.length()) | 858 if (query.length()) { |
| 858 StringAppendF(output, "Collections of histograms for %s\n", query.c_str()); | 859 base::StringAppendF(output, "Collections of histograms for %s\n", |
| 859 else | 860 query.c_str()); |
| 861 } else { |
| 860 output->append("Collections of all histograms\n"); | 862 output->append("Collections of all histograms\n"); |
| 863 } |
| 861 | 864 |
| 862 Histograms snapshot; | 865 Histograms snapshot; |
| 863 GetSnapshot(query, &snapshot); | 866 GetSnapshot(query, &snapshot); |
| 864 for (Histograms::iterator it = snapshot.begin(); | 867 for (Histograms::iterator it = snapshot.begin(); |
| 865 it != snapshot.end(); | 868 it != snapshot.end(); |
| 866 ++it) { | 869 ++it) { |
| 867 (*it)->WriteAscii(true, "\n", output); | 870 (*it)->WriteAscii(true, "\n", output); |
| 868 output->append("\n"); | 871 output->append("\n"); |
| 869 } | 872 } |
| 870 } | 873 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 snapshot->push_back(it->second); | 908 snapshot->push_back(it->second); |
| 906 } | 909 } |
| 907 } | 910 } |
| 908 | 911 |
| 909 // static | 912 // static |
| 910 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; | 913 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; |
| 911 // static | 914 // static |
| 912 Lock* StatisticsRecorder::lock_ = NULL; | 915 Lock* StatisticsRecorder::lock_ = NULL; |
| 913 // static | 916 // static |
| 914 bool StatisticsRecorder::dump_on_exit_ = false; | 917 bool StatisticsRecorder::dump_on_exit_ = false; |
| OLD | NEW |