Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(219)

Side by Side Diff: base/metrics/histogram.cc

Issue 2965083002: Reduce Histogram object size. (Closed)
Patch Set: added TODO to remove unnecessary parameters Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/metrics/histogram.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 // In most cases, the bucket-count, minimum, and maximum values are known 157 // In most cases, the bucket-count, minimum, and maximum values are known
158 // when the code is written and so are passed in explicitly. In other 158 // when the code is written and so are passed in explicitly. In other
159 // cases (such as with a CustomHistogram), they are calculated dynamically 159 // cases (such as with a CustomHistogram), they are calculated dynamically
160 // at run-time. In the latter case, those ctor parameters are zero and 160 // at run-time. In the latter case, those ctor parameters are zero and
161 // the results extracted from the result of CreateRanges(). 161 // the results extracted from the result of CreateRanges().
162 if (bucket_count_ == 0) { 162 if (bucket_count_ == 0) {
163 bucket_count_ = static_cast<uint32_t>(registered_ranges->bucket_count()); 163 bucket_count_ = static_cast<uint32_t>(registered_ranges->bucket_count());
164 minimum_ = registered_ranges->range(1); 164 minimum_ = registered_ranges->range(1);
165 maximum_ = registered_ranges->range(bucket_count_ - 1); 165 maximum_ = registered_ranges->range(bucket_count_ - 1);
166 } 166 }
167 DCHECK_EQ(minimum_, registered_ranges->range(1));
168 DCHECK_EQ(maximum_, registered_ranges->range(bucket_count_ - 1));
167 169
168 // Try to create the histogram using a "persistent" allocator. As of 170 // Try to create the histogram using a "persistent" allocator. As of
169 // 2016-02-25, the availability of such is controlled by a base::Feature 171 // 2016-02-25, the availability of such is controlled by a base::Feature
170 // that is off by default. If the allocator doesn't exist or if 172 // that is off by default. If the allocator doesn't exist or if
171 // allocating from it fails, code below will allocate the histogram from 173 // allocating from it fails, code below will allocate the histogram from
172 // the process heap. 174 // the process heap.
173 PersistentHistogramAllocator::Reference histogram_ref = 0; 175 PersistentHistogramAllocator::Reference histogram_ref = 0;
174 std::unique_ptr<HistogramBase> tentative_histogram; 176 std::unique_ptr<HistogramBase> tentative_histogram;
175 PersistentHistogramAllocator* allocator = GlobalHistogramAllocator::Get(); 177 PersistentHistogramAllocator* allocator = GlobalHistogramAllocator::Get();
176 if (allocator) { 178 if (allocator) {
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 } else { 353 } else {
352 DCHECK_GT(0, delta); 354 DCHECK_GT(0, delta);
353 UMA_HISTOGRAM_COUNTS("Histogram.InconsistentCountLow", -delta); 355 UMA_HISTOGRAM_COUNTS("Histogram.InconsistentCountLow", -delta);
354 if (-delta > kCommonRaceBasedCountMismatch) 356 if (-delta > kCommonRaceBasedCountMismatch)
355 inconsistencies |= COUNT_LOW_ERROR; 357 inconsistencies |= COUNT_LOW_ERROR;
356 } 358 }
357 } 359 }
358 return inconsistencies; 360 return inconsistencies;
359 } 361 }
360 362
363 Sample Histogram::declared_min() const {
364 if (bucket_ranges_->bucket_count() < 2)
365 return -1;
366 return bucket_ranges_->range(1);
367 }
368
369 Sample Histogram::declared_max() const {
370 if (bucket_ranges_->bucket_count() < 2)
371 return -1;
372 return bucket_ranges_->range(bucket_ranges_->bucket_count() - 1);
373 }
374
361 Sample Histogram::ranges(uint32_t i) const { 375 Sample Histogram::ranges(uint32_t i) const {
362 return bucket_ranges_->range(i); 376 return bucket_ranges_->range(i);
363 } 377 }
364 378
365 uint32_t Histogram::bucket_count() const { 379 uint32_t Histogram::bucket_count() const {
366 return static_cast<uint32_t>(bucket_ranges_->bucket_count()); 380 return static_cast<uint32_t>(bucket_ranges_->bucket_count());
367 } 381 }
368 382
369 // static 383 // static
370 bool Histogram::InspectConstructionArguments(const std::string& name, 384 bool Histogram::InspectConstructionArguments(const std::string& name,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 return unlogged_samples_->id(); 438 return unlogged_samples_->id();
425 } 439 }
426 440
427 HistogramType Histogram::GetHistogramType() const { 441 HistogramType Histogram::GetHistogramType() const {
428 return HISTOGRAM; 442 return HISTOGRAM;
429 } 443 }
430 444
431 bool Histogram::HasConstructionArguments(Sample expected_minimum, 445 bool Histogram::HasConstructionArguments(Sample expected_minimum,
432 Sample expected_maximum, 446 Sample expected_maximum,
433 uint32_t expected_bucket_count) const { 447 uint32_t expected_bucket_count) const {
434 return ((expected_minimum == declared_min_) && 448 return (expected_bucket_count == bucket_count() &&
435 (expected_maximum == declared_max_) && 449 expected_minimum == declared_min() &&
436 (expected_bucket_count == bucket_count())); 450 expected_maximum == declared_max());
437 } 451 }
438 452
439 void Histogram::Add(int value) { 453 void Histogram::Add(int value) {
440 AddCount(value, 1); 454 AddCount(value, 1);
441 } 455 }
442 456
443 void Histogram::AddCount(int value, int count) { 457 void Histogram::AddCount(int value, int count) {
444 DCHECK_EQ(0, ranges(0)); 458 DCHECK_EQ(0, ranges(0));
445 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count())); 459 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count()));
446 460
447 if (value > kSampleType_MAX - 1) 461 if (value > kSampleType_MAX - 1)
448 value = kSampleType_MAX - 1; 462 value = kSampleType_MAX - 1;
449 if (value < 0) 463 if (value < 0)
450 value = 0; 464 value = 0;
451 if (count <= 0) { 465 if (count <= 0) {
452 NOTREACHED(); 466 NOTREACHED();
453 return; 467 return;
454 } 468 }
455 unlogged_samples_->Accumulate(value, count); 469 unlogged_samples_->Accumulate(value, count);
456 470
457 FindAndRunCallback(value); 471 FindAndRunCallback(value);
458 } 472 }
459 473
460 std::unique_ptr<HistogramSamples> Histogram::SnapshotSamples() const { 474 std::unique_ptr<HistogramSamples> Histogram::SnapshotSamples() const {
461 return SnapshotAllSamples(); 475 return SnapshotAllSamples();
462 } 476 }
463 477
464 std::unique_ptr<HistogramSamples> Histogram::SnapshotDelta() { 478 std::unique_ptr<HistogramSamples> Histogram::SnapshotDelta() {
479 #if DCHECK_IS_ON()
465 DCHECK(!final_delta_created_); 480 DCHECK(!final_delta_created_);
481 #endif
482
466 // The code below has subtle thread-safety guarantees! All changes to 483 // The code below has subtle thread-safety guarantees! All changes to
467 // the underlying SampleVectors use atomic integer operations, which guarantee 484 // the underlying SampleVectors use atomic integer operations, which guarantee
468 // eventual consistency, but do not guarantee full synchronization between 485 // eventual consistency, but do not guarantee full synchronization between
469 // different entries in the SampleVector. In particular, this means that 486 // different entries in the SampleVector. In particular, this means that
470 // concurrent updates to the histogram might result in the reported sum not 487 // concurrent updates to the histogram might result in the reported sum not
471 // matching the individual bucket counts; or there being some buckets that are 488 // matching the individual bucket counts; or there being some buckets that are
472 // logically updated "together", but end up being only partially updated when 489 // logically updated "together", but end up being only partially updated when
473 // a snapshot is captured. Note that this is why it's important to subtract 490 // a snapshot is captured. Note that this is why it's important to subtract
474 // exactly the snapshotted unlogged samples, rather than simply resetting the 491 // exactly the snapshotted unlogged samples, rather than simply resetting the
475 // vector: this way, the next snapshot will include any concurrent updates 492 // vector: this way, the next snapshot will include any concurrent updates
476 // missed by the current snapshot. 493 // missed by the current snapshot.
477 494
478 std::unique_ptr<HistogramSamples> snapshot = SnapshotUnloggedSamples(); 495 std::unique_ptr<HistogramSamples> snapshot = SnapshotUnloggedSamples();
479 unlogged_samples_->Subtract(*snapshot); 496 unlogged_samples_->Subtract(*snapshot);
480 logged_samples_->Add(*snapshot); 497 logged_samples_->Add(*snapshot);
481 498
482 return snapshot; 499 return snapshot;
483 } 500 }
484 501
485 std::unique_ptr<HistogramSamples> Histogram::SnapshotFinalDelta() const { 502 std::unique_ptr<HistogramSamples> Histogram::SnapshotFinalDelta() const {
503 #if DCHECK_IS_ON()
486 DCHECK(!final_delta_created_); 504 DCHECK(!final_delta_created_);
487 final_delta_created_ = true; 505 final_delta_created_ = true;
506 #endif
488 507
489 return SnapshotUnloggedSamples(); 508 return SnapshotUnloggedSamples();
490 } 509 }
491 510
492 void Histogram::AddSamples(const HistogramSamples& samples) { 511 void Histogram::AddSamples(const HistogramSamples& samples) {
493 unlogged_samples_->Add(samples); 512 unlogged_samples_->Add(samples);
494 } 513 }
495 514
496 bool Histogram::AddSamplesFromPickle(PickleIterator* iter) { 515 bool Histogram::AddSamplesFromPickle(PickleIterator* iter) {
497 return unlogged_samples_->AddFromPickle(iter); 516 return unlogged_samples_->AddFromPickle(iter);
(...skipping 14 matching lines...) Expand all
512 bool Histogram::SerializeInfoImpl(Pickle* pickle) const { 531 bool Histogram::SerializeInfoImpl(Pickle* pickle) const {
513 DCHECK(bucket_ranges()->HasValidChecksum()); 532 DCHECK(bucket_ranges()->HasValidChecksum());
514 return pickle->WriteString(histogram_name()) && 533 return pickle->WriteString(histogram_name()) &&
515 pickle->WriteInt(flags()) && 534 pickle->WriteInt(flags()) &&
516 pickle->WriteInt(declared_min()) && 535 pickle->WriteInt(declared_min()) &&
517 pickle->WriteInt(declared_max()) && 536 pickle->WriteInt(declared_max()) &&
518 pickle->WriteUInt32(bucket_count()) && 537 pickle->WriteUInt32(bucket_count()) &&
519 pickle->WriteUInt32(bucket_ranges()->checksum()); 538 pickle->WriteUInt32(bucket_ranges()->checksum());
520 } 539 }
521 540
541 // TODO(bcwhite): Remove minimum/maximum parameters from here and call chain.
522 Histogram::Histogram(const std::string& name, 542 Histogram::Histogram(const std::string& name,
523 Sample minimum, 543 Sample minimum,
524 Sample maximum, 544 Sample maximum,
525 const BucketRanges* ranges) 545 const BucketRanges* ranges)
526 : HistogramBase(name), 546 : HistogramBase(name), bucket_ranges_(ranges) {
527 bucket_ranges_(ranges),
528 declared_min_(minimum),
529 declared_max_(maximum) {
530 // TODO(bcwhite): Make this a DCHECK once crbug/734049 is resolved. 547 // TODO(bcwhite): Make this a DCHECK once crbug/734049 is resolved.
531 CHECK(ranges) << name << ": " << minimum << "-" << maximum; 548 CHECK(ranges) << name << ": " << minimum << "-" << maximum;
532 unlogged_samples_.reset(new SampleVector(HashMetricName(name), ranges)); 549 unlogged_samples_.reset(new SampleVector(HashMetricName(name), ranges));
533 logged_samples_.reset(new SampleVector(unlogged_samples_->id(), ranges)); 550 logged_samples_.reset(new SampleVector(unlogged_samples_->id(), ranges));
534 } 551 }
535 552
536 Histogram::Histogram(const std::string& name, 553 Histogram::Histogram(const std::string& name,
537 Sample minimum, 554 Sample minimum,
538 Sample maximum, 555 Sample maximum,
539 const BucketRanges* ranges, 556 const BucketRanges* ranges,
540 const DelayedPersistentAllocation& counts, 557 const DelayedPersistentAllocation& counts,
541 const DelayedPersistentAllocation& logged_counts, 558 const DelayedPersistentAllocation& logged_counts,
542 HistogramSamples::Metadata* meta, 559 HistogramSamples::Metadata* meta,
543 HistogramSamples::Metadata* logged_meta) 560 HistogramSamples::Metadata* logged_meta)
544 : HistogramBase(name), 561 : HistogramBase(name), bucket_ranges_(ranges) {
545 bucket_ranges_(ranges),
546 declared_min_(minimum),
547 declared_max_(maximum) {
548 // TODO(bcwhite): Make this a DCHECK once crbug/734049 is resolved. 562 // TODO(bcwhite): Make this a DCHECK once crbug/734049 is resolved.
549 CHECK(ranges) << name << ": " << minimum << "-" << maximum; 563 CHECK(ranges) << name << ": " << minimum << "-" << maximum;
550 unlogged_samples_.reset( 564 unlogged_samples_.reset(
551 new PersistentSampleVector(HashMetricName(name), ranges, meta, counts)); 565 new PersistentSampleVector(HashMetricName(name), ranges, meta, counts));
552 logged_samples_.reset(new PersistentSampleVector( 566 logged_samples_.reset(new PersistentSampleVector(
553 unlogged_samples_->id(), ranges, logged_meta, logged_counts)); 567 unlogged_samples_->id(), ranges, logged_meta, logged_counts));
554 } 568 }
555 569
556 Histogram::~Histogram() { 570 Histogram::~Histogram() {
557 } 571 }
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 Sample sample = custom_ranges[i]; 1235 Sample sample = custom_ranges[i];
1222 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) 1236 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1)
1223 return false; 1237 return false;
1224 if (sample != 0) 1238 if (sample != 0)
1225 has_valid_range = true; 1239 has_valid_range = true;
1226 } 1240 }
1227 return has_valid_range; 1241 return has_valid_range;
1228 } 1242 }
1229 1243
1230 } // namespace base 1244 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/histogram.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698