-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Finer concurrency in 'MetricType.observe' / 'MetricType.collect' #59
Conversation
return histogram | ||
} else { | ||
let newHistogram = PromHistogram<T, U>(histogram.name, histogram.help, labels, Buckets(histogram.upperBounds), self) | ||
histogram.subHistograms.append(newHistogram) | ||
guard let prometheus = prometheus else { fatalError("Lingering Histogram") } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm can this actually ever happen or just annoyance because that weak there that shoulnd't really manifest in reality?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is a weak reference thing. I think reference to Prometheus is redundant, I'll try to track down its origins and potentially remove if indeed unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah i see the error just moved around, it was there before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice this looks very good, thanks for measuring and the PR Anton!
return histogram | ||
} else { | ||
let newHistogram = PromHistogram<T, U>(histogram.name, histogram.help, labels, Buckets(histogram.upperBounds), self) | ||
histogram.subHistograms.append(newHistogram) | ||
guard let prometheus = prometheus else { fatalError("Lingering Histogram") } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah i see the error just moved around, it was there before.
subHistogram.labels.le = "" | ||
let (buckets, subHistograms, labels) = self.lock.withLock { | ||
(self.buckets, self.subHistograms, self.labels) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for the PR!
Every metric type has a lock that's taken for the whole duration of consuming a metric value, and also for the whole duration of observe. This PR puts as much computations out of critical section as we can afford, which results in a significant performance boost.
With these changes,
Lock.withLock
takes only 25% ofPromHistogram.observe
, of which half is locking/unlocking and the other half iscollection.filter
.Reducing the scope of locking helps bringing
lock.withLock
to 50% ofPromHistogram.observe
. ChangingsubHistograms
from array to map, reduces it further to25%
Checklist
Motivation and Context
This PR brings concurrency optimisations that result in better emission latencies.
Description
Every MetricType's lock is now only held during access to corresponding state in a thread safe manner, all computations are moved outside critical section.
subHistograms is now a
Map
instead of array.