SumType
JG
someone at somewhere.com
Thu Oct 28 20:37:11 UTC 2021
On Thursday, 28 October 2021 at 13:30:53 UTC, Paul Backus wrote:
> On Thursday, 28 October 2021 at 09:02:52 UTC, JG wrote:
>> I am heavily using SumType (which I like very much). The
>> problem I am having is that is seems to be causing slow
>> compile times (as can be observed by profiling during the
>> compile). The problem seems to be with match (which is
>> extremely convenient to use). I looked at the code and it does
>> the only reasonable thing too do which is to test each handler
>> against each type. The slow compile time makes development
>> slower and less pleasant, so I am thinking of replacing
>> SumType with my own tagged union and writing out the switches
>> by hand. However, I really don't like this idea since it makes
>> the code less readable and more prone to errors. Any
>> suggestions?
>
> Hi, I'm the author of `SumType`. Thanks for bringing this to my
> attention. The good news is, I have not put a lot of effort so
> far into micro-optimizing the compile-time performance of
> `match`, so there is almost certainly room for improvement.
>
> If you have an example of the kind of code you are seeing poor
> compile-time performance for, I'd be happy to use it as a
> benchmark/profiling target. Any profiling data you've collected
> would also be helpful.
>
> I've created issues for this on Bugzilla and the sumtype Github
> repository:
>
> https://issues.dlang.org/show_bug.cgi?id=22447
> https://github.com/pbackus/sumtype/issues/76
Thank you so much for your response (and thanks for the hard work
that went into SumType). Here is a rather contrived example which
compiles in around 9 seconds on my machine.
import std;
struct A1 {int val; }
struct A2 {int val; }
struct A3 {int val; }
struct A4 {int val; }
struct A5 {int val; }
struct A6 {int val; }
struct A7 {int val; }
struct A8 {int val; }
struct A9 {int val; }
struct A10 {int val; }
struct A11 {int val; }
struct A12 {int val; }
struct A13 {int val; }
struct A14 {int val; }
alias A =
SumType!(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14);
T asserter(T)() { assert(0); }
auto op(A1 x, A1 y, A1 z) { return x.val + y.val + z.val; }
auto op(A2 x, A2 y, A2 z) { return x.val + y.val - z.val; }
auto op(A3 x, A3 y, A3 z) { return x.val + y.val * z.val; }
auto op(A4 x, A4 y, A4 z) { return x.val + y.val & z.val; }
auto op(A5 x, A5 y, A5 z) { return x.val - y.val + z.val; }
auto op(A6 x, A6 y, A6 z) { return x.val - y.val - z.val; }
auto op(A7 x, A7 y, A7 z) { return x.val - y.val * z.val; }
auto op(A8 x, A8 y, A8 z) { return x.val - y.val & z.val; }
auto op(A9 x, A9 y, A9 z) { return x.val * y.val + z.val; }
auto op(A10 x, A10 y, A10 z) { return x.val * y.val - z.val; }
auto op(A11 x, A11 y, A11 z) { return x.val * y.val * z.val; }
auto op(A12 x, A12 y, A12 z) { return x.val * y.val & z.val; }
auto op(A13 x, A13 y, A13 z) { return x.val & y.val + z.val; }
auto op(A14 x, A14 y, A14 z) { return x.val & y.val - z.val; }
auto op(A a, A b, A c) {
return a.match!(
x=>b.match!(
y=>c.match!(z=>op(x,y,z),
_=>asserter!int),
_=>asserter!int));
}
auto op2(A a, A b, A c) {
alias doMatch = match!(
(x, y, z) => op(x,y,z),
(_1, _2, _3) => asserter!int
);
return doMatch(a, b, c);
}
void main()
{
A a = A1(12);
A b = A1(13);
A c = A1(14);
assert(op(a,b,c)==39);
assert(op2(a,b,c)==39);
}
More information about the Digitalmars-d-learn
mailing list