Improve performance of partition

This commit is contained in:
Andrei Alexandrescu 2016-01-11 12:25:29 -05:00
parent 9c7f0dabc3
commit 06cb165a47

View file

@ -362,6 +362,33 @@ Range partition(alias predicate,
{ {
// Inspired from www.stepanovpapers.com/PAM3-partition_notes.pdf, // Inspired from www.stepanovpapers.com/PAM3-partition_notes.pdf,
// section "Bidirectional Partition Algorithm (Hoare)" // section "Bidirectional Partition Algorithm (Hoare)"
static if (isDynamicArray!Range)
{
// For dynamic arrays prefer index-based manipulation
if (!r.length) return r;
size_t lo = 0, hi = r.length - 1;
for (;;)
{
for (;;)
{
if (lo > hi) return r[lo .. $];
if (!pred(r[lo])) break;
++lo;
}
// found the left bound
assert(lo <= hi);
for (;;)
{
if (lo == hi) return r[lo .. $];
if (pred(r[hi])) break;
--hi;
}
// found the right bound, swap & make progress
swap(r[lo++], r[hi--]);
}
}
else
{
auto result = r; auto result = r;
for (;;) for (;;)
{ {
@ -396,6 +423,7 @@ Range partition(alias predicate,
r.popBack(); r.popBack();
} }
} }
}
} }
/// ///