Question about additional type safety and performance #8763
-
I'd like to use single field structs to eliminate primitive obsession. This doesn't lead to a performance hit in .NET. Is it possible for it to not have a performance hit in Orleans for method parameters? I've tried I'd also like to do the same for grain keys but I can't see how to do this easily without wrapping the |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
@AnthonyLloyd There will be a small perf hit. I'm fairly sure the added complexity in the code generator to avoid that small perf cost is not worthwhile. You can craft your own codecs if you really want to, eg by copying As for grain keys, they should be UTF8 encoded strings so that they can be displayed in logs, traces, metrics, error messages, etc. You can create your own using Here's an example of how to write your own codec & copier for a custom primitive wrapper: [Immutable]
public readonly struct MyValueType(double value)
{
public double Value { get; } = value;
}
[RegisterSerializer]
public sealed class MyValueTypeCodec : IFieldCodec<MyValueType>
{
public void WriteField<TBufferWriter>(
ref Writer<TBufferWriter> writer,
uint fieldIdDelta,
Type expectedType,
MyValueType value)
where TBufferWriter : IBufferWriter<byte>
{
ReferenceCodec.MarkValueField(writer.Session);
writer.WriteFieldHeader(fieldIdDelta, expectedType, typeof(MyValueType), WireType.Fixed64);
writer.WriteUInt64(BitConverter.DoubleToUInt64Bits(value.Value));
}
public MyValueType ReadValue<TInput>(ref Reader<TInput> reader, Field field)
{
ReferenceCodec.MarkValueField(reader.Session);
return new(BitConverter.UInt64BitsToDouble(reader.ReadUInt64()));
}
}
[RegisterCopier]
public sealed class MyValueTypeCopier : IDeepCopier<MyValueType>
{
public MyValueType DeepCopy(MyValueType input, CopyContext context) => input;
} |
Beta Was this translation helpful? Give feedback.
@AnthonyLloyd There will be a small perf hit. I'm fairly sure the added complexity in the code generator to avoid that small perf cost is not worthwhile. You can craft your own codecs if you really want to, eg by copying
DoubleCodec
and modifying it to usePrice
instead. I don't think this is worthwhile, though, and if you ever add additional fields, you'd need to adjust your codec to handle that by checking the wire type and switching behavior.As for grain keys, they should be UTF8 encoded strings so that they can be displayed in logs, traces, metrics, error messages, etc. You can create your own using
GrainId.Create(type, key)
and use theIGrainFactory
overload which accepts aGrainId
.H…