-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use a union struct for an optimal PythonConstant
#235
base: main
Are you sure you want to change the base?
Conversation
thanks. The memory consumption of the parser for the source generation is low-priority. I'm having a hard time understanding the code on this one and prefer the other PR. Granted, my C# knowledge is intermediate (a way from advanced). |
Conflicts resolved: - src/CSnakes.SourceGeneration/Parser/PythonParser.Constants.cs - src/CSnakes.SourceGeneration/Parser/Types/PythonConstant.cs - src/CSnakes.SourceGeneration/Reflection/ArgumentReflection.cs - src/CSnakes.Tests/TokenizerTests.cs
I understand.
FWIW, the overall design here is two-fold (and thus non-obvious). First, to optimise the storage space via [StructLayout(LayoutKind.Explicit)]
private readonly struct Union
{
[FieldOffset(0)] public readonly bool Boolean;
[FieldOffset(0)] public readonly long Int64;
[FieldOffset(0)] public readonly double Double;
} This would be akin to a union Data {
int flag; // bool
long lval
double dval;
char* pstr;
}; The public readonly struct PythonConstant
{
readonly Union union; // union storage for value primitives (bool, long & double)
readonly string? str; // storage for string reference
} This means that the size of The The switch (parameter.DefaultValue)
{
case null: /* ... */ break;
case { HexidecimalIntegerValue: { } v }: /* ... */ break;
case { BinaryIntegerValue: { } v }: /* ... */ break;
case { IntegerValue: { } v and >= int.MinValue and <= int.MaxValue }: /* ... */ break;
case { IntegerValue: { } v }: /* ... */ break;
case { StringValue: { } v }: /* ... */ break;
case { FloatValue: { } v }: /* ... */ break;
case { BoolValue: true }: /* ... */ break;
case { BoolValue: false }: /* ... */ break;
case { IsNone: true }: /* ... */ break;
} Whether this PR is approved or not, I've expanded on the design if it can help with the decision. |
This PR is an alternative design to the refactoring proposed in PR #234. Only one of the two should be merged.
In contrast to PR #234, which uses a type hierarchy of subclasses to represent a union of all
PythonConstant
types, this uses a singlestruct
as a union. It has the following benefits with respect to the current implementation and the one proposed in PR #234:bool
,long
anddouble
) and another for strings, instead of the sum of storage needed for all value types.default(PythonConstant)
), it representsNone
.ArgumentReflection.ArgumentSyntax
for application). In fact,PythonConstant.ConstantType
can even be made private since it's no longer used outside ofPythonConstant
.The main motivation for accepting this design over PR #234 is zero heap footprint.