Skip to content

Commit ebc0a7b

Browse files
yfeldblumfacebook-github-bot
authored andcommitted
optimize bits of HistogramWrapper::add
Summary: * Move deferred initialization in `ensureApplySpec` from the fast-path to the slow-path. * Use `ThreadLocalPtr<TLHistogram>` v.s. `ThreadLocal<shared_ptr<TLHistogram>>` to reduce object size and to remove one level of indirection. `ThreadLocalPtr<T>` has special support for being assigned `shared_ptr<T>`. * Put spec on heap and delete it after deferred init to reduce its memory consumption. Reviewed By: Gownta Differential Revision: D66590811 fbshipit-source-id: 10ed7c5219bd6cfde0ca7d6d18ce52040ab239bb
1 parent ec0310d commit ebc0a7b

File tree

2 files changed

+26
-22
lines changed

2 files changed

+26
-22
lines changed

fb303/ThreadCachedServiceData.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,19 @@ SubminuteMinuteOnlyTimeseriesWrapper::templateExportedStat() {
113113
return *obj.get();
114114
}
115115

116+
FOLLY_NOINLINE void HistogramWrapper::doApplySpecLocked() {
117+
std::exchange(spec_, {})->apply(key_, ServiceData::get());
118+
}
119+
120+
FOLLY_NOINLINE ThreadCachedServiceData::TLHistogram*
121+
HistogramWrapper::tcHistogramSlow() {
122+
folly::call_once(once_, &HistogramWrapper::doApplySpecLocked, this);
123+
auto& local = ThreadCachedServiceData::getStatsThreadLocal();
124+
auto const histogram = local->getHistogramSafe(key_);
125+
tlHistogram_.reset(histogram);
126+
return histogram.get();
127+
}
128+
116129
ThreadCachedServiceData::StatsThreadLocal&
117130
ThreadCachedServiceData::getStatsThreadLocal() {
118131
static folly::Indestructible<ThreadCachedServiceData::StatsThreadLocal>

fb303/ThreadCachedServiceData.h

+13-22
Original file line numberDiff line numberDiff line change
@@ -1204,39 +1204,30 @@ class HistogramWrapper {
12041204
int64_t min,
12051205
int64_t max,
12061206
const Args&... args)
1207-
: key_(key), spec_(bucketWidth, min, max, args...) {}
1207+
: key_(key),
1208+
spec_(std::make_unique<internal::HistogramSpec>(
1209+
bucketWidth,
1210+
min,
1211+
max,
1212+
args...)) {}
12081213

12091214
void add(int64_t value = 1) {
1210-
ensureApplySpec();
12111215
tcHistogram()->addValue(value);
12121216
}
12131217

12141218
protected:
1215-
void doApplySpecLocked() {
1216-
spec_.apply(key_, ThreadCachedServiceData::get());
1217-
}
1218-
FOLLY_ALWAYS_INLINE void ensureApplySpec() {
1219-
// minimize inline slow path size by passing the callback this way
1220-
folly::call_once(once_, &HistogramWrapper::doApplySpecLocked, this);
1221-
}
1222-
1223-
inline ThreadCachedServiceData::TLHistogram* tcHistogram() {
1224-
ThreadCachedServiceData::TLHistogram* cached = tlHistogram_->get();
1225-
if (cached) {
1226-
return cached;
1227-
}
1219+
void doApplySpecLocked();
12281220

1229-
auto histogram =
1230-
ThreadCachedServiceData::getStatsThreadLocal()->getHistogramSafe(key_);
1231-
*tlHistogram_ = histogram;
1232-
return histogram.get();
1221+
FOLLY_ALWAYS_INLINE ThreadCachedServiceData::TLHistogram* tcHistogram() {
1222+
ThreadCachedServiceData::TLHistogram* cached = tlHistogram_.get();
1223+
return FOLLY_LIKELY(!!cached) ? cached : tcHistogramSlow();
12331224
}
1225+
ThreadCachedServiceData::TLHistogram* tcHistogramSlow();
12341226

12351227
folly::once_flag once_;
12361228
std::string key_;
1237-
internal::HistogramSpec spec_;
1238-
folly::ThreadLocal<std::shared_ptr<ThreadCachedServiceData::TLHistogram>>
1239-
tlHistogram_;
1229+
std::unique_ptr<internal::HistogramSpec> spec_; // ptr for memory-size
1230+
folly::ThreadLocalPtr<ThreadCachedServiceData::TLHistogram> tlHistogram_;
12401231
};
12411232

12421233
class MinuteOnlyHistogram : public HistogramWrapper {

0 commit comments

Comments
 (0)