mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 00:14:35 +03:00
dag: add another fast path for IdSet::push
Summary: Partially address a PERF comment. The path would be useful in upcoming changes. `cargo bench --bench spanset` now shows: push_span (middle) 0.710 ms Previously it was: push_span (middle) 5.750 ms Note the difference will be larger if the IdSet contains more spans. Practically, we are thinking about 10k spans scale. Reviewed By: DurhamG Differential Revision: D31708352 fbshipit-source-id: cccbbab80fb997a50d5cc2536b076ad604f9b8fe
This commit is contained in:
parent
53340d92a7
commit
563a73b7e3
@ -626,9 +626,50 @@ impl SpanSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// PERF: There is a better way to do this by bisecting
|
// Fast path: modify a span in-place.
|
||||||
// spans and insert in-place. For now, this code path is
|
// higher H1---->L1 cur H2---->L2 lower H3---->L3
|
||||||
// rarely used.
|
// safe range L1-2---------------->H3+2
|
||||||
|
// Exceeding the safe range would cause spans to overlap and this path cannot
|
||||||
|
// handle that.
|
||||||
|
let idx = match self
|
||||||
|
.spans
|
||||||
|
.bsearch_by(|probe| (span.high + 1).cmp(&probe.low))
|
||||||
|
{
|
||||||
|
Ok(idx) => idx,
|
||||||
|
Err(idx) => idx,
|
||||||
|
};
|
||||||
|
for idx in [idx] {
|
||||||
|
if let Some(cur) = self.spans.get(idx) {
|
||||||
|
// Not overlap with span?
|
||||||
|
if span.high + 1 < cur.low || cur.high + 1 < span.low {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Might merge with a higher span? (Not in safe range)
|
||||||
|
if idx > 0 {
|
||||||
|
if let Some(higher) = self.spans.get(idx - 1) {
|
||||||
|
if span.high + 1 >= higher.low {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Might merge with a lower span? (Not in safe range)
|
||||||
|
if let Some(lower) = self.spans.get(idx + 1) {
|
||||||
|
if lower.high + 1 >= span.low {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Passed all checks. Merge the span.
|
||||||
|
let mut cur = &mut self.spans[idx];
|
||||||
|
cur.high = cur.high.max(span.high);
|
||||||
|
cur.low = cur.low.min(span.low);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// PERF: There might be a better way to do this by bisecting
|
||||||
|
// spans and insert or delete in-place. For now, this code
|
||||||
|
// path remains not optimized since it is rarely used.
|
||||||
*self = self.union(&SpanSet::from(span))
|
*self = self.union(&SpanSet::from(span))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user