Skip to content

Commit 7f19bb9

Browse files
committed
Merge pull request XRPLF#242 from tdfischer/perf-timer-destructors
Refactor PerfStepTimer to automatically stop on destruct
2 parents 8438a19 + 6614a48 commit 7f19bb9

File tree

6 files changed

+70
-69
lines changed

6 files changed

+70
-69
lines changed

db/db_impl.cc

+14-18
Original file line numberDiff line numberDiff line change
@@ -3407,7 +3407,7 @@ Status DBImpl::GetImpl(const ReadOptions& options,
34073407
ColumnFamilyHandle* column_family, const Slice& key,
34083408
std::string* value, bool* value_found) {
34093409
StopWatch sw(env_, stats_, DB_GET);
3410-
PERF_TIMER_AUTO(get_snapshot_time);
3410+
PERF_TIMER_GUARD(get_snapshot_time);
34113411

34123412
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
34133413
auto cfd = cfh->cfd();
@@ -3431,27 +3431,27 @@ Status DBImpl::GetImpl(const ReadOptions& options,
34313431
// merge_operands will contain the sequence of merges in the latter case.
34323432
LookupKey lkey(key, snapshot);
34333433
PERF_TIMER_STOP(get_snapshot_time);
3434+
34343435
if (sv->mem->Get(lkey, value, &s, merge_context, *cfd->options())) {
34353436
// Done
34363437
RecordTick(stats_, MEMTABLE_HIT);
34373438
} else if (sv->imm->Get(lkey, value, &s, merge_context, *cfd->options())) {
34383439
// Done
34393440
RecordTick(stats_, MEMTABLE_HIT);
34403441
} else {
3441-
PERF_TIMER_START(get_from_output_files_time);
3442-
3442+
PERF_TIMER_GUARD(get_from_output_files_time);
34433443
sv->current->Get(options, lkey, value, &s, &merge_context, value_found);
3444-
PERF_TIMER_STOP(get_from_output_files_time);
34453444
RecordTick(stats_, MEMTABLE_MISS);
34463445
}
34473446

3448-
PERF_TIMER_START(get_post_process_time);
3447+
{
3448+
PERF_TIMER_GUARD(get_post_process_time);
34493449

3450-
ReturnAndCleanupSuperVersion(cfd, sv);
3450+
ReturnAndCleanupSuperVersion(cfd, sv);
34513451

3452-
RecordTick(stats_, NUMBER_KEYS_READ);
3453-
RecordTick(stats_, BYTES_READ, value->size());
3454-
PERF_TIMER_STOP(get_post_process_time);
3452+
RecordTick(stats_, NUMBER_KEYS_READ);
3453+
RecordTick(stats_, BYTES_READ, value->size());
3454+
}
34553455
return s;
34563456
}
34573457

@@ -3461,7 +3461,7 @@ std::vector<Status> DBImpl::MultiGet(
34613461
const std::vector<Slice>& keys, std::vector<std::string>* values) {
34623462

34633463
StopWatch sw(env_, stats_, DB_MULTIGET);
3464-
PERF_TIMER_AUTO(get_snapshot_time);
3464+
PERF_TIMER_GUARD(get_snapshot_time);
34653465

34663466
SequenceNumber snapshot;
34673467

@@ -3537,7 +3537,7 @@ std::vector<Status> DBImpl::MultiGet(
35373537
}
35383538

35393539
// Post processing (decrement reference counts and record statistics)
3540-
PERF_TIMER_START(get_post_process_time);
3540+
PERF_TIMER_GUARD(get_post_process_time);
35413541
autovector<SuperVersion*> superversions_to_delete;
35423542

35433543
// TODO(icanadi) do we need lock here or just around Cleanup()?
@@ -3910,7 +3910,7 @@ Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) {
39103910
if (my_batch == nullptr) {
39113911
return Status::Corruption("Batch is nullptr!");
39123912
}
3913-
PERF_TIMER_AUTO(write_pre_and_post_process_time);
3913+
PERF_TIMER_GUARD(write_pre_and_post_process_time);
39143914
Writer w(&mutex_);
39153915
w.batch = my_batch;
39163916
w.sync = options.sync;
@@ -4043,7 +4043,7 @@ Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) {
40434043

40444044
uint64_t log_size = 0;
40454045
if (!options.disableWAL) {
4046-
PERF_TIMER_START(write_wal_time);
4046+
PERF_TIMER_GUARD(write_wal_time);
40474047
Slice log_entry = WriteBatchInternal::Contents(updates);
40484048
status = log_->AddRecord(log_entry);
40494049
total_log_size_ += log_entry.size();
@@ -4061,10 +4061,9 @@ Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) {
40614061
status = log_->file()->Sync();
40624062
}
40634063
}
4064-
PERF_TIMER_STOP(write_wal_time);
40654064
}
40664065
if (status.ok()) {
4067-
PERF_TIMER_START(write_memtable_time);
4066+
PERF_TIMER_GUARD(write_memtable_time);
40684067

40694068
status = WriteBatchInternal::InsertInto(
40704069
updates, column_family_memtables_.get(), false, 0, this, false);
@@ -4076,8 +4075,6 @@ Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) {
40764075
// into the memtable would result in a state that some write ops might
40774076
// have succeeded in memtable but Status reports error for all writes.
40784077

4079-
PERF_TIMER_STOP(write_memtable_time);
4080-
40814078
SetTickerCount(stats_, SEQUENCE_NUMBER, last_sequence);
40824079
}
40834080
PERF_TIMER_START(write_pre_and_post_process_time);
@@ -4111,7 +4108,6 @@ Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) {
41114108
RecordTick(stats_, WRITE_TIMEDOUT);
41124109
}
41134110

4114-
PERF_TIMER_STOP(write_pre_and_post_process_time);
41154111
return status;
41164112
}
41174113

db/db_iter.cc

+18-11
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,8 @@ void DBIter::Next() {
194194
// NOTE: In between, saved_key_ can point to a user key that has
195195
// a delete marker
196196
inline void DBIter::FindNextUserEntry(bool skipping) {
197-
PERF_TIMER_AUTO(find_next_user_entry_time);
197+
PERF_TIMER_GUARD(find_next_user_entry_time);
198198
FindNextUserEntryInternal(skipping);
199-
PERF_TIMER_STOP(find_next_user_entry_time);
200199
}
201200

202201
// Actual implementation of DBIter::FindNextUserEntry()
@@ -557,9 +556,12 @@ void DBIter::Seek(const Slice& target) {
557556
saved_key_.Clear();
558557
// now savved_key is used to store internal key.
559558
saved_key_.SetInternalKey(target, sequence_);
560-
PERF_TIMER_AUTO(seek_internal_seek_time);
561-
iter_->Seek(saved_key_.GetKey());
562-
PERF_TIMER_STOP(seek_internal_seek_time);
559+
560+
{
561+
PERF_TIMER_GUARD(seek_internal_seek_time);
562+
iter_->Seek(saved_key_.GetKey());
563+
}
564+
563565
if (iter_->Valid()) {
564566
direction_ = kForward;
565567
ClearSavedValue();
@@ -577,9 +579,12 @@ void DBIter::SeekToFirst() {
577579
}
578580
direction_ = kForward;
579581
ClearSavedValue();
580-
PERF_TIMER_AUTO(seek_internal_seek_time);
581-
iter_->SeekToFirst();
582-
PERF_TIMER_STOP(seek_internal_seek_time);
582+
583+
{
584+
PERF_TIMER_GUARD(seek_internal_seek_time);
585+
iter_->SeekToFirst();
586+
}
587+
583588
if (iter_->Valid()) {
584589
FindNextUserEntry(false /* not skipping */);
585590
} else {
@@ -595,9 +600,11 @@ void DBIter::SeekToLast() {
595600
}
596601
direction_ = kReverse;
597602
ClearSavedValue();
598-
PERF_TIMER_AUTO(seek_internal_seek_time);
599-
iter_->SeekToLast();
600-
PERF_TIMER_STOP(seek_internal_seek_time);
603+
604+
{
605+
PERF_TIMER_GUARD(seek_internal_seek_time);
606+
iter_->SeekToLast();
607+
}
601608

602609
PrevInternal();
603610
}

db/memtable.cc

+1-2
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ bool MemTable::Get(const LookupKey& key, std::string* value, Status* s,
422422
// Avoiding recording stats for speed.
423423
return false;
424424
}
425-
PERF_TIMER_AUTO(get_from_memtable_time);
425+
PERF_TIMER_GUARD(get_from_memtable_time);
426426

427427
Slice user_key = key.user_key();
428428
bool found_final_value = false;
@@ -452,7 +452,6 @@ bool MemTable::Get(const LookupKey& key, std::string* value, Status* s,
452452
if (!found_final_value && merge_in_progress) {
453453
*s = Status::MergeInProgress("");
454454
}
455-
PERF_TIMER_STOP(get_from_memtable_time);
456455
PERF_COUNTER_ADD(get_from_memtable_count, 1);
457456
return found_final_value;
458457
}

table/format.cc

+8-6
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,13 @@ Status ReadBlock(RandomAccessFile* file, const Footer& footer,
211211
const ReadOptions& options, const BlockHandle& handle,
212212
Slice* contents, /* result of reading */ char* buf) {
213213
size_t n = static_cast<size_t>(handle.size());
214+
Status s;
215+
216+
{
217+
PERF_TIMER_GUARD(block_read_time);
218+
s = file->Read(handle.offset(), n + kBlockTrailerSize, contents, buf);
219+
}
214220

215-
PERF_TIMER_AUTO(block_read_time);
216-
Status s = file->Read(handle.offset(), n + kBlockTrailerSize, contents, buf);
217-
PERF_TIMER_MEASURE(block_read_time);
218221
PERF_COUNTER_ADD(block_read_count, 1);
219222
PERF_COUNTER_ADD(block_read_byte, n + kBlockTrailerSize);
220223

@@ -228,6 +231,7 @@ Status ReadBlock(RandomAccessFile* file, const Footer& footer,
228231
// Check the crc of the type and the block contents
229232
const char* data = contents->data(); // Pointer to where Read put the data
230233
if (options.verify_checksums) {
234+
PERF_TIMER_GUARD(block_checksum_time);
231235
uint32_t value = DecodeFixed32(data + n + 1);
232236
uint32_t actual = 0;
233237
switch (footer.checksum()) {
@@ -247,7 +251,6 @@ Status ReadBlock(RandomAccessFile* file, const Footer& footer,
247251
if (!s.ok()) {
248252
return s;
249253
}
250-
PERF_TIMER_STOP(block_checksum_time);
251254
}
252255
return s;
253256
}
@@ -265,7 +268,7 @@ Status DecompressBlock(BlockContents* result, size_t block_size,
265268
result->cachable = false;
266269
result->heap_allocated = false;
267270

268-
PERF_TIMER_AUTO(block_decompress_time);
271+
PERF_TIMER_GUARD(block_decompress_time);
269272
rocksdb::CompressionType compression_type =
270273
static_cast<rocksdb::CompressionType>(data[n]);
271274
// If the caller has requested that the block not be uncompressed
@@ -295,7 +298,6 @@ Status DecompressBlock(BlockContents* result, size_t block_size,
295298
} else {
296299
s = UncompressBlockContents(data, n, result);
297300
}
298-
PERF_TIMER_STOP(block_decompress_time);
299301
return s;
300302
}
301303

table/merger.cc

+7-10
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,12 @@ class MergingIterator : public Iterator {
116116
// Invalidate the heap.
117117
use_heap_ = false;
118118
IteratorWrapper* first_child = nullptr;
119-
PERF_TIMER_DECLARE();
120119

121120
for (auto& child : children_) {
122-
PERF_TIMER_START(seek_child_seek_time);
123-
child.Seek(target);
124-
PERF_TIMER_STOP(seek_child_seek_time);
121+
{
122+
PERF_TIMER_GUARD(seek_child_seek_time);
123+
child.Seek(target);
124+
}
125125
PERF_COUNTER_ADD(seek_child_seek_count, 1);
126126

127127
if (child.Valid()) {
@@ -134,24 +134,21 @@ class MergingIterator : public Iterator {
134134
} else {
135135
// We have more than one children with valid keys. Initialize
136136
// the heap and put the first child into the heap.
137-
PERF_TIMER_START(seek_min_heap_time);
137+
PERF_TIMER_GUARD(seek_min_heap_time);
138138
ClearHeaps();
139139
minHeap_.push(first_child);
140-
PERF_TIMER_STOP(seek_min_heap_time);
141140
}
142141
}
143142
if (use_heap_) {
144-
PERF_TIMER_START(seek_min_heap_time);
143+
PERF_TIMER_GUARD(seek_min_heap_time);
145144
minHeap_.push(&child);
146-
PERF_TIMER_STOP(seek_min_heap_time);
147145
}
148146
}
149147
}
150148
if (use_heap_) {
151149
// If heap is valid, need to put the smallest key to curent_.
152-
PERF_TIMER_START(seek_min_heap_time);
150+
PERF_TIMER_GUARD(seek_min_heap_time);
153151
FindSmallest();
154-
PERF_TIMER_STOP(seek_min_heap_time);
155152
} else {
156153
// The heap is not valid, then the current_ iterator is the first
157154
// one, or null if there is no first child.

util/perf_context_imp.h

+22-22
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ namespace rocksdb {
1111

1212
#if defined(NPERF_CONTEXT) || defined(IOS_CROSS_COMPILE)
1313

14-
#define PERF_TIMER_DECLARE()
15-
#define PERF_TIMER_START(metric)
16-
#define PERF_TIMER_AUTO(metric)
14+
#define PERF_TIMER_GUARD(metric)
1715
#define PERF_TIMER_MEASURE(metric)
1816
#define PERF_TIMER_STOP(metric)
17+
#define PERF_TIMER_START(metric)
1918
#define PERF_COUNTER_ADD(metric, value)
2019

2120
#else
@@ -24,10 +23,15 @@ extern __thread PerfLevel perf_level;
2423

2524
class PerfStepTimer {
2625
public:
27-
PerfStepTimer()
26+
PerfStepTimer(uint64_t* metric)
2827
: enabled_(perf_level >= PerfLevel::kEnableTime),
2928
env_(enabled_ ? Env::Default() : nullptr),
30-
start_(0) {
29+
start_(0),
30+
metric_(metric) {
31+
}
32+
33+
~PerfStepTimer() {
34+
Stop();
3135
}
3236

3337
void Start() {
@@ -36,17 +40,17 @@ class PerfStepTimer {
3640
}
3741
}
3842

39-
void Measure(uint64_t* metric) {
43+
void Measure() {
4044
if (start_) {
4145
uint64_t now = env_->NowNanos();
42-
*metric += now - start_;
46+
*metric_ += now - start_;
4347
start_ = now;
4448
}
4549
}
4650

47-
void Stop(uint64_t* metric) {
51+
void Stop() {
4852
if (start_) {
49-
*metric += env_->NowNanos() - start_;
53+
*metric_ += env_->NowNanos() - start_;
5054
start_ = 0;
5155
}
5256
}
@@ -55,29 +59,25 @@ class PerfStepTimer {
5559
const bool enabled_;
5660
Env* const env_;
5761
uint64_t start_;
62+
uint64_t* metric_;
5863
};
5964

60-
// Declare the local timer object to be used later on
61-
#define PERF_TIMER_DECLARE() \
62-
PerfStepTimer perf_step_timer;
65+
// Stop the timer and update the metric
66+
#define PERF_TIMER_STOP(metric) \
67+
perf_step_timer_ ## metric.Stop();
6368

64-
// Set start time of the timer
6569
#define PERF_TIMER_START(metric) \
66-
perf_step_timer.Start();
70+
perf_step_timer_ ## metric.Start();
6771

6872
// Declare and set start time of the timer
69-
#define PERF_TIMER_AUTO(metric) \
70-
PerfStepTimer perf_step_timer; \
71-
perf_step_timer.Start();
73+
#define PERF_TIMER_GUARD(metric) \
74+
PerfStepTimer perf_step_timer_ ## metric(&(perf_context.metric)); \
75+
perf_step_timer_ ## metric.Start();
7276

7377
// Update metric with time elapsed since last START. start time is reset
7478
// to current timestamp.
7579
#define PERF_TIMER_MEASURE(metric) \
76-
perf_step_timer.Measure(&(perf_context.metric));
77-
78-
// Update metric with time elapsed since last START. But start time is not set.
79-
#define PERF_TIMER_STOP(metric) \
80-
perf_step_timer.Stop(&(perf_context.metric));
80+
perf_step_timer_ ## metric.Measure();
8181

8282
// Increase metric value
8383
#define PERF_COUNTER_ADD(metric, value) \

0 commit comments

Comments
 (0)