Skip to content

Commit 41a3710

Browse files
Ramon Cano Apariciocopybara-github
authored andcommitted
Avoid computing md5 hash multiple times in Sparse Histogram.
This change is a continuation on reusing the already computed hash for the metric name instead of recomputing it each time. Create an extra parameter in PersistentHistogramAllocator::AllocateHistogram so we can pass name_hash as a parameter. Change-Id: Iae7964c58e09cd3945483cba6e05da89b652db00 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6469736 Reviewed-by: Robert Kaplow <[email protected]> Commit-Queue: Ramon Cano Aparicio <[email protected]> Reviewed-by: Luc Nguyen <[email protected]> Cr-Commit-Position: refs/heads/main@{#1458097} NOKEYCHECK=True GitOrigin-RevId: eb4e315ee8e550eaf1a0e5d5a844ef80129df9fd
1 parent c80d6da commit 41a3710

File tree

5 files changed

+42
-22
lines changed

5 files changed

+42
-22
lines changed

metrics/histogram.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ HistogramBase* Histogram::Factory::Build() {
198198
// CreateHistogram, which calls HashMetricName. We already have the hash,
199199
// so we could pass it in.
200200
tentative_histogram = allocator->AllocateHistogram(
201-
histogram_type_, name_, minimum_, maximum_, registered_ranges, flags_,
202-
&histogram_ref);
201+
histogram_type_, name_, name_hash, minimum_, maximum_,
202+
registered_ranges, flags_, &histogram_ref);
203203
}
204204

205205
// Handle the case where no persistent allocator is present or the

metrics/persistent_histogram_allocator.cc

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
310310
// Check that metadata is reasonable: metric_name is non-empty,
311311
// ID fields have been loaded with a hash of the name (0 is considered
312312
// unset/invalid).
313+
uint64_t name_hash = HashMetricName(*durable_metric_name);
313314
if (durable_metric_name->empty() ||
314315
UNSAFE_TODO(reinterpret_cast<const char*>(data)[alloc_size - 1]) !=
315316
'\0' ||
@@ -321,15 +322,16 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
321322
// could just verify the name length based on the overall alloc length,
322323
// but that doesn't work because the allocated block may have been
323324
// aligned to the next boundary value.
324-
HashMetricName(*durable_metric_name) != data->samples_metadata.id) {
325+
name_hash != data->samples_metadata.id) {
325326
return nullptr;
326327
}
327-
return CreateHistogram(data, durable_metric_name);
328+
return CreateHistogram(data, durable_metric_name, name_hash);
328329
}
329330

330331
std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
331332
HistogramType histogram_type,
332333
std::string_view name,
334+
uint64_t name_hash,
333335
int minimum,
334336
int maximum,
335337
const BucketRanges* bucket_ranges,
@@ -438,7 +440,7 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
438440
DurableStringView durable_name(
439441
std::string_view(histogram_data->name, name.size()));
440442
std::unique_ptr<HistogramBase> histogram =
441-
CreateHistogram(histogram_data, durable_name);
443+
CreateHistogram(histogram_data, durable_name, name_hash);
442444
DCHECK(histogram);
443445
DCHECK_NE(0U, histogram_data->samples_metadata.id);
444446
DCHECK_NE(0U, histogram_data->logged_metadata.id);
@@ -549,7 +551,8 @@ void PersistentHistogramAllocator::ClearLastCreatedReferenceForTesting() {
549551

550552
std::unique_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram(
551553
PersistentHistogramData* histogram_data_ptr,
552-
DurableStringView durable_name) {
554+
DurableStringView durable_name,
555+
uint64_t name_hash) {
553556
if (!histogram_data_ptr) {
554557
return nullptr;
555558
}
@@ -561,7 +564,7 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram(
561564
// Sparse histograms are quite different so handle them as a special case.
562565
if (histogram_data_ptr->histogram_type == SPARSE_HISTOGRAM) {
563566
std::unique_ptr<HistogramBase> histogram =
564-
SparseHistogram::PersistentCreate(this, durable_name,
567+
SparseHistogram::PersistentCreate(this, durable_name, name_hash,
565568
&histogram_data_ptr->samples_metadata,
566569
&histogram_data_ptr->logged_metadata);
567570
DCHECK(histogram);
@@ -654,6 +657,8 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram(
654657

655658
// Create the right type of histogram.
656659
std::unique_ptr<HistogramBase> histogram;
660+
// TODO(crbug.com/394149163): We can pass the name_hash to the histogram
661+
// constructors, and then use it here.
657662
switch (histogram_type) {
658663
case HISTOGRAM:
659664
histogram = Histogram::PersistentCreate(

metrics/persistent_histogram_allocator.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ class BASE_EXPORT PersistentHistogramAllocator {
254254
std::unique_ptr<HistogramBase> AllocateHistogram(
255255
HistogramType histogram_type,
256256
std::string_view name,
257+
uint64_t name_hash,
257258
int minimum,
258259
int maximum,
259260
const BucketRanges* bucket_ranges,
@@ -340,7 +341,8 @@ class BASE_EXPORT PersistentHistogramAllocator {
340341
// `alloc_size` returned from the `memory_allocator`.
341342
std::unique_ptr<HistogramBase> CreateHistogram(
342343
PersistentHistogramData* histogram_data_ptr,
343-
DurableStringView durable_name);
344+
DurableStringView durable_name,
345+
uint64_t name_hash);
344346

345347
// Gets or creates an object in the global StatisticsRecorder matching
346348
// the `histogram` passed. Null is returned if one was not found and

metrics/sparse_histogram.cc

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,18 @@ HistogramBase* SparseHistogram::FactoryGet(std::string_view name,
4343
std::unique_ptr<HistogramBase> tentative_histogram;
4444
PersistentHistogramAllocator* allocator = GlobalHistogramAllocator::Get();
4545
if (allocator) {
46-
// TODO(crbug.com/394149163): AllocateHistogram ends up calling
47-
// HashMetricName. We already have the hash, so we could pass it in.
4846
tentative_histogram = allocator->AllocateHistogram(
49-
SPARSE_HISTOGRAM, name, 0, 0, nullptr, flags, &histogram_ref);
47+
SPARSE_HISTOGRAM, name, name_hash, /*minimum=*/0, /*maximum=*/0,
48+
/*bucket_ranges=*/nullptr, flags, &histogram_ref);
5049
}
5150

5251
// Handle the case where no persistent allocator is present or the
5352
// persistent allocation fails (perhaps because it is full).
5453
if (!tentative_histogram) {
5554
DCHECK(!histogram_ref); // Should never have been set.
5655
flags &= ~HistogramBase::kIsPersistent;
57-
// TODO(crbug.com/394149163): SparseHistogram constructor ends up calling
58-
// HashMetricName. We already have the hash, so we could pass it in.
59-
tentative_histogram.reset(new SparseHistogram(GetPermanentName(name)));
56+
tentative_histogram.reset(
57+
new SparseHistogram(GetPermanentName(name), name_hash));
6058
tentative_histogram->SetFlags(flags);
6159
}
6260

@@ -95,10 +93,11 @@ HistogramBase* SparseHistogram::FactoryGet(std::string_view name,
9593
std::unique_ptr<HistogramBase> SparseHistogram::PersistentCreate(
9694
PersistentHistogramAllocator* allocator,
9795
DurableStringView durable_name,
96+
uint64_t name_hash,
9897
HistogramSamples::Metadata* meta,
9998
HistogramSamples::Metadata* logged_meta) {
100-
return WrapUnique(
101-
new SparseHistogram(allocator, durable_name, meta, logged_meta));
99+
return WrapUnique(new SparseHistogram(allocator, durable_name, name_hash,
100+
meta, logged_meta));
102101
}
103102

104103
SparseHistogram::~SparseHistogram() = default;
@@ -207,12 +206,19 @@ void SparseHistogram::SerializeInfoImpl(Pickle* pickle) const {
207206
}
208207

209208
SparseHistogram::SparseHistogram(DurableStringView durable_name)
209+
: SparseHistogram(durable_name, HashMetricName(*durable_name)) {}
210+
211+
SparseHistogram::SparseHistogram(DurableStringView durable_name,
212+
uint64_t name_hash)
210213
: HistogramBase(durable_name),
211-
unlogged_samples_(new SampleMap(HashMetricName(*durable_name))),
212-
logged_samples_(new SampleMap(unlogged_samples_->id())) {}
214+
unlogged_samples_(new SampleMap(name_hash)),
215+
logged_samples_(new SampleMap(unlogged_samples_->id())) {
216+
DCHECK_EQ(name_hash, HashMetricName(*durable_name)) << "Name hash mismatch";
217+
}
213218

214219
SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator,
215220
DurableStringView durable_name,
221+
uint64_t name_hash,
216222
HistogramSamples::Metadata* meta,
217223
HistogramSamples::Metadata* logged_meta)
218224
: HistogramBase(durable_name),
@@ -226,12 +232,12 @@ SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator,
226232
// "active" samples use, for convenience purposes, an ID matching
227233
// that of the histogram while the "logged" samples use that number
228234
// plus 1.
229-
unlogged_samples_(new PersistentSampleMap(HashMetricName(*durable_name),
230-
allocator,
231-
meta)),
235+
unlogged_samples_(new PersistentSampleMap(name_hash, allocator, meta)),
232236
logged_samples_(new PersistentSampleMap(unlogged_samples_->id() + 1,
233237
allocator,
234-
logged_meta)) {}
238+
logged_meta)) {
239+
DCHECK_EQ(name_hash, HashMetricName(*durable_name)) << "Name hash mismatch";
240+
}
235241

236242
HistogramBase* SparseHistogram::DeserializeInfoImpl(PickleIterator* iter) {
237243
std::string histogram_name;

metrics/sparse_histogram.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class BASE_EXPORT SparseHistogram : public HistogramBase {
3636
static std::unique_ptr<HistogramBase> PersistentCreate(
3737
PersistentHistogramAllocator* allocator,
3838
DurableStringView name,
39+
uint64_t name_hash,
3940
HistogramSamples::Metadata* meta,
4041
HistogramSamples::Metadata* logged_meta);
4142

@@ -69,8 +70,14 @@ class BASE_EXPORT SparseHistogram : public HistogramBase {
6970
// Clients should always use FactoryGet to create SparseHistogram.
7071
explicit SparseHistogram(DurableStringView name);
7172

73+
// Same as above, but takes a pre-computed `name_hash`. This function is more
74+
// efficient as it avoids recomputing the hash if it's already known. The
75+
// `name_hash` must be the hash of `name`, this is enforced with a DCHECK.
76+
SparseHistogram(DurableStringView name, uint64_t name_hash);
77+
7278
SparseHistogram(PersistentHistogramAllocator* allocator,
7379
DurableStringView name,
80+
uint64_t name_hash,
7481
HistogramSamples::Metadata* meta,
7582
HistogramSamples::Metadata* logged_meta);
7683

0 commit comments

Comments
 (0)