Divide & Conquer divides, but doesn't conquer
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Mon May 25 01:25:53 UTC 2020
On 5/24/20 8:44 PM, Timon Gehr wrote:
> On 25.05.20 01:40, Andrei Alexandrescu wrote:
>> ...
>>
>> So it seems divide et impera doesn't quite help with certain recursive
>> templates.
>
> Assuming the cost of a template instantiation is linear in the number of
> template arguments, the first version has running time Θ(n log n) while
> the second version has running time Θ(n²).
Of course. However, I'm assuming most of a template instantiation's cost
is fixed.
There are other algorithms looking at in std.meta. Consider Reverse:
template Reverse(TList...)
{
static if (TList.length <= 1)
{
alias Reverse = TList;
}
else
{
alias Reverse =
AliasSeq!(
Reverse!(TList[$/2 .. $ ]),
Reverse!(TList[ 0 .. $/2]));
}
}
The recurrence formula for complexity is:
T(0) = k;
T(1) = k;
T(n) = 2 * T(n/2) + k
Again, I assume instantiating AliasSeq with two lists of any lengths has
the same cost k. That makes complexity linear. So is the complexity of
the simpler implementation:
template Reverse(TList...)
{
static if (TList.length <= 1)
{
alias Reverse = TList;
}
else
{
alias Reverse =
AliasSeq!(Reverse!(TList[1 .. $]), TList[0]);
}
}
But this insantiates half the templates, so it goes easier on resources.
This makes the use of the halving strategy not only an unnecessary
distraction, but a less efficient choice.
There are other unnecessary (and/or unnecessarily baroque) artifacts in
std.meta, such as EraseAllN. Far as I can tell it's unnecessary because
NoDuplicates can be implemented without it (and if I'm not wrong, at the
same complexity).
std.meta is due for a serious review.
More information about the Digitalmars-d
mailing list