Closed Opiumtm closed 4 years ago
@Opiumtm,
Unfortunately, just removing the reference wouldn't achieve much as many features of Succinc<T> return an Option<T>
, so there would still be a GC overhead of a temporary object from which the struct would be created.
To properly address this, those features would need to change to return Maybe<T>
. So I'm going to schedule looking at this as part of the V3.2.0 release (the one after the next release).
I'd suggest to write performance benchmark tests first. For example, introduction of singleton value for Option
Good point, @megafinz. I shall do that.
@megafinz as a general rule, small enough structs are considered better than small classes for performance purposes.
It's why ValueTask
and ValueTuple
was introduced in C#7.
overhead of passing them around
Often that overhead can be mitigated via passing structs by ref. C#7 provide extended support for by ref structs passing, allow ref struct locals and ref struct return.
Often that overhead can be mitigated via passing structs by ref. C#7 provide extended support for by ref structs passing, allow ref struct locals and ref struct return.
Good point, thanks, that simplifies things quite a bit.
@Opiumtm,
I'm uncomfortable with the idea of having to replace classes with structs and lots of ref returns as I feel that would complicate things, just to provide performance enhancements. But I shall experiment once v3.1 is released.
Of course, if either you or @megafinz wish to submit any performance tests for me to base my experiments on, then those PR's will be very gratefully received, as performance testing is not a strong point for me.
@DavidArno I propose to have two versions of it. After all, there are Tuple<>
and ValueTuple<>
, Task<T>
and ValueTask<T>
- you understood the idea. Developer would choose what is appropriate in his specific case.
and lots of ref returns
Generally small enough structs such as Maybe<T>
do not require ref
to pass data around as this struct is already small and cheap to copy. For the most cases Maybe<T>
would contain reference type as T
(so struct keep and copy only small reference to original T
-value), but having additional reference with Option<T>
inside (or with standalone use of Option<T>
) require runtime to allocate and keep two GC handles instead of just one for original T
-typed reference. It's 100% more GC handles and that 100% more GC handles are essentially excessive and truly the waste of resources.
Maybe<T>
has been removed and Option<T>
is now a read-only struct. Closing this as no longer required therefore.
https://github.com/DavidArno/SuccincT/blob/master/src/SuccincT/Options/Maybe%7BT%7D.cs
Although
Maybe<T>
appears as struct, it have internal reference to instance of reference typeMajor purpose of structs isn't to avoid "Null reference exceptions". Major purpose of structs is to avoid memory allocations on heap which can be critical under heavy load.
Option<T>
andMaybe<T>
are small enough to be structs as heap allocations and then GC to release references are more performance-impacting than copy of such small structs around.Maybe<T>
retain unnecessary GC handle (internal reference-type instance ofOption<T>
), so it don't provide performance benefits of structs.