Optimize DBIter::Prev() by reducing stack overhead
Summary: It looks like we are spending significant amount of time creating std::deque<std::string> every time we do Iterator::Prev() {F921567} By using merge_operands_ as a DBIter data member w create it once and reduce this overhead and see ~30% performance improvement when using Iterator::Prev() on hot data Orignal performance ``` DEBUG_LEVEL=0 make db_bench -j64 && ./db_bench --benchmarks="readreverse" --db="/dev/shm/bench_prev_opt/" --use_existing_db --disable_auto_compactions readreverse : 0.713 micros/op 1402219 ops/sec; 155.1 MB/s readreverse : 0.609 micros/op 1641386 ops/sec; 181.6 MB/s readreverse : 0.684 micros/op 1461150 ops/sec; 161.6 MB/s readreverse : 0.629 micros/op 1589842 ops/sec; 175.9 MB/s readreverse : 0.647 micros/op 1544530 ops/sec; 170.9 MB/s ``` After optimization ``` DEBUG_LEVEL=0 make db_bench -j64 && ./db_bench --benchmarks="readreverse" --db="/dev/shm/bench_prev_opt/" --use_existing_db --disable_auto_compactions readreverse : 0.488 micros/op 2051189 ops/sec; 226.9 MB/s readreverse : 0.505 micros/op 1980892 ops/sec; 219.1 MB/s readreverse : 0.541 micros/op 1846971 ops/sec; 204.3 MB/s readreverse : 0.497 micros/op 2013612 ops/sec; 222.8 MB/s readreverse : 0.480 micros/op 2082665 ops/sec; 230.4 MB/s ``` Test Plan: make check -j64 Reviewers: sdong, anthony, rven, igor, yhchiang Reviewed By: yhchiang Subscribers: jkedgar, dhruba Differential Revision: https://reviews.facebook.net/D52563
This commit is contained in:
parent
73c31377bb
commit
8c71eb5afc
@ -190,6 +190,8 @@ class DBIter: public Iterator {
|
||||
IterKey prefix_start_;
|
||||
bool prefix_same_as_start_;
|
||||
bool iter_pinned_;
|
||||
// List of operands for merge operator.
|
||||
std::deque<std::string> merge_operands_;
|
||||
|
||||
// No copying allowed
|
||||
DBIter(const DBIter&);
|
||||
@ -493,8 +495,7 @@ void DBIter::PrevInternal() {
|
||||
// saved_value_
|
||||
bool DBIter::FindValueForCurrentKey() {
|
||||
assert(iter_->Valid());
|
||||
// Contains operands for merge operator.
|
||||
std::deque<std::string> operands;
|
||||
merge_operands_.clear();
|
||||
// last entry before merge (could be kTypeDeletion, kTypeSingleDeletion or
|
||||
// kTypeValue)
|
||||
ValueType last_not_merge_type = kTypeDeletion;
|
||||
@ -514,19 +515,19 @@ bool DBIter::FindValueForCurrentKey() {
|
||||
last_key_entry_type = ikey.type;
|
||||
switch (last_key_entry_type) {
|
||||
case kTypeValue:
|
||||
operands.clear();
|
||||
merge_operands_.clear();
|
||||
saved_value_ = iter_->value().ToString();
|
||||
last_not_merge_type = kTypeValue;
|
||||
break;
|
||||
case kTypeDeletion:
|
||||
case kTypeSingleDeletion:
|
||||
operands.clear();
|
||||
merge_operands_.clear();
|
||||
last_not_merge_type = last_key_entry_type;
|
||||
PERF_COUNTER_ADD(internal_delete_skipped_count, 1);
|
||||
break;
|
||||
case kTypeMerge:
|
||||
assert(user_merge_operator_ != nullptr);
|
||||
operands.push_back(iter_->value().ToString());
|
||||
merge_operands_.push_back(iter_->value().ToString());
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
@ -548,8 +549,9 @@ bool DBIter::FindValueForCurrentKey() {
|
||||
if (last_not_merge_type == kTypeDeletion) {
|
||||
StopWatchNano timer(env_, statistics_ != nullptr);
|
||||
PERF_TIMER_GUARD(merge_operator_time_nanos);
|
||||
user_merge_operator_->FullMerge(saved_key_.GetKey(), nullptr, operands,
|
||||
&saved_value_, logger_);
|
||||
user_merge_operator_->FullMerge(saved_key_.GetKey(), nullptr,
|
||||
merge_operands_, &saved_value_,
|
||||
logger_);
|
||||
RecordTick(statistics_, MERGE_OPERATION_TOTAL_TIME,
|
||||
timer.ElapsedNanos());
|
||||
} else {
|
||||
@ -560,7 +562,8 @@ bool DBIter::FindValueForCurrentKey() {
|
||||
StopWatchNano timer(env_, statistics_ != nullptr);
|
||||
PERF_TIMER_GUARD(merge_operator_time_nanos);
|
||||
user_merge_operator_->FullMerge(saved_key_.GetKey(), &temp_slice,
|
||||
operands, &saved_value_, logger_);
|
||||
merge_operands_, &saved_value_,
|
||||
logger_);
|
||||
RecordTick(statistics_, MERGE_OPERATION_TOTAL_TIME,
|
||||
timer.ElapsedNanos());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user