-
Notifications
You must be signed in to change notification settings - Fork 830
Description
Found this while investigating the performance issues with @cmeeren's implementation of Array.tryPickV, see #6781 (comment).
As an example, take the following code:
type MyNormalDU =
| Case1
| Case2
| Case3
| Case4
| Case5
| Case6
| Case7
| Case8
| Case9This compiles into the following constructors (I removed attributes for ease of reading):
internal MyStructDU(int _tag, bool flag)
{
this.Tag = _tag;
}
internal MyStructDU(int _tag, byte num)
{
this.Tag = _tag;
}
internal MyStructDU(int _tag, sbyte num)
{
this.Tag = _tag;
}
internal MyStructDU(int _tag, char chr)
{
this.Tag = _tag;
}
internal MyStructDU(int _tag, short num)
{
this.Tag = _tag;
}
internal MyStructDU(int _tag, int num)
{
this.Tag = _tag;
}
internal MyStructDU(int _tag, ushort num)
{
this.Tag = _tag;
}
internal MyStructDU(int _tag, uint num, bool flag)
{
this.Tag = _tag;
}
internal MyStructDU(int _tag, uint num, byte num)
{
this.Tag = _tag;
}There wasn't anything about this implementation detail in the relevant RFC, but my guess is this is to disambiguate constructors for same-type DU fields, as there's a clear "countable" use of all the build-in types up until 32 bit.
Optimization ideas for struct DUs
These redundant parameters lead to overhead in constructing the types, as the extra param needs to be put on the stack, even though it is always zero (false, '\0', 0uy etc). There used to be other optimization issues with overloaded constructors in structs w.r.t. JIT optimizations, but I haven't been able to verify that that is still the case.
Either way, I propose we improve this, which would consequently improve ValueOption as well:
- These constructors are only ever called from a single place, we can emit simple struct-init code there instead with the proper value(s), if any
- For no-value multi-case struct-DUs, only the
_tagneeds to be set, ctor overloads are not needed - Any top-case initialization without a value can be optimized to just init the struct to zero (i.e.
ValueNone, orCase1above)
If this is made possible, voption can be improved to issue the same null-check (i.e. br.false or br.true) as for option to check for ValueNone, which dramatically speeds up the current implementation which calls get_Tag() and compares it with 0.
This would also open the way to implement overlapping DU cases in an overlapping internal struct, which dramatically reduces space occupied by struct DUs.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status