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