You can ask, but someone else will have to answer. Sorry.

On Tue, Feb 22, 2022 at 9:52 PM Clinton Mead <clintonm...@gmail.com> wrote:
>
> Thanks David. Can I ask why? Is it because the first constructor is treated 
> specially? (perhaps because it has zeroed tag bits)? Or is it just because 
> there's always an if/else chain in order of the constructor definition 
> regardless of the order of the case statement so the higher up the list the 
> better?
>
> On Wed, Feb 23, 2022 at 1:34 PM David Feuer <david.fe...@gmail.com> wrote:
>>
>> I can answer one of your questions for sure: the order of your case branches 
>> doesn't matter at all. However, the order of the data constructors in the 
>> type declaration does matter. Put your most likely one first.
>>
>> On Tue, Feb 22, 2022, 9:09 PM Clinton Mead <clintonm...@gmail.com> wrote:
>>>
>>> Hi All
>>>
>>> I'm developing an unbounded integer type, which I won't go into the details 
>>> here but in some circumstances has better performance than the standard 
>>> "Integer".
>>>
>>> Anyway, whilst there are complex cases, the most common case is a standard 
>>> machine int multiplication.
>>>
>>> Hence I want the type to be optimised for that case.
>>>
>>> I'm going to have a few constructors, anyway, so I first considered 
>>> something like this:
>>>
>>> `data MyInt = BasicZero | BasicPos Word | BasicNeg Word | ComplexPosA ... | 
>>> ComplexNegA ... | ComplexPosB ... | ComplexNegB ...`
>>>
>>> I'd naturally make the "Word"s in "BasicPos" and "BasicNeg" strict/unpack, 
>>> hopefully eliminating the indirection, or perhaps just making them 
>>> primitive directly.
>>>
>>> This has 7 constructors, which quite nicely I believe fits into the three 
>>> spare bits in a 64 bit pointer which GHC optimises I believe.
>>>
>>> However, this approach I thought of because I assumed that GHC would do a 
>>> switch style statement on the constructors, so once I have more than one I 
>>> might as well have as many as I want (well, up to 7, until I lose the 
>>> optimisation).
>>>
>>> But if GHC compiles this to a "if ... else if..." chain, a better 
>>> representation is the following:
>>>
>>> `data MyInt = BasicInt Int | ComplexPosA ... | ComplexNegA ... | 
>>> ComplexPosB ... | ComplexNegB ...`
>>>
>>> That way I can match against BasicInt first, and knock that out of the way 
>>> as my "hot" case. However, using "Int" instead of "Word" does make the 
>>> logic a bit more complex, but it may be worth it if I'm reducing the number 
>>> of patterns I have to check against for all arguments.
>>>
>>> I was just wondering if anyone could share some insight on what GHC does in 
>>> these circumstances? For example, does the order I list my cases in a case 
>>> statement matter if they're non-overlapping? Will GHC match them in the 
>>> order I list, or will it just make them into a switch statement so it 
>>> doesn't matter if I reorder them?
>>>
>>> I guess I could benchmark all this (and probably will) but some insights 
>>> and general guidance would be good.
>>>
>>> Thanks,
>>> Clinton
>>> _______________________________________________
>>> Glasgow-haskell-users mailing list
>>> Glasgow-haskell-users@haskell.org
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users

Reply via email to