Skip to content
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

About my similar projects #4

Open
Cricle opened this issue Dec 14, 2023 · 2 comments
Open

About my similar projects #4

Cricle opened this issue Dec 14, 2023 · 2 comments

Comments

@Cricle
Copy link

Cricle commented Dec 14, 2023

In my project UnionType, I also try to use memory overlap to store all type(decimal,Guid,object also support by use GCHandle weak or pin)

For object store I use 8bytes store intptr 8bytes store type name intptr.

In benchmark decimal test, there was a good result.

But I don't know if this will help in a real project, I always try to expand coreclr internal class, always thinks why it will be set internal.

I'm 96% covered in unit tests, but object store design will be hard for any time. The GC of the class instance should be controlled, and no one wants memory leakage.

Thanks.

@Cricle
Copy link
Author

Cricle commented Dec 15, 2023

I try to add benchmark code in this project

StoreLong.cs

+ [MemoryDiagnoser]
[DisassemblyDiagnoser]
public class StoreLong
{
    [Benchmark]
    public long ValueAsPerf()
    {
        Value value = new(42L);
        return value.As<long>();
    }

    [Benchmark(Baseline = true)]
    public long ValueTryPerf()
    {
        Value value = new(42L);
        value.TryGetValue(out long result);
        return result;
    }

    [Benchmark]
    public long ValueCastOutPerf()
    {
        Value value = new(42L);
        return (long)value;
    }

    [Benchmark]
    public long ValueCastInPerf()
    {
        Value value = 42L;
        value.TryGetValue(out long result);
        return result;
    }
+    [Benchmark]
+    public long UnionValueAsPerf()
+    {
+        UnionValue value = default;
+        value.Long = 42L;
+        return value;
+    }
+    [Benchmark]
+    public long UnionCaseInPerf()
+    {
+        UnionValue value = 42L;
+        return value;
+    }
}
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19045
AMD Ryzen 7 5800H with Radeon Graphics, 1 CPU, 16 logical and 8 physical cores
.NET SDK=8.0.100
  [Host]     : .NET 6.0.25 (6.0.2523.51912), X64 RyuJIT
  DefaultJob : .NET 6.0.25 (6.0.2523.51912), X64 RyuJIT

Method Mean Error StdDev Ratio RatioSD Code Size Allocated
ValueAsPerf 2.5328 ns 0.0778 ns 0.0926 ns 2.76 0.19 138 B -
ValueTryPerf 0.9200 ns 0.0374 ns 0.0332 ns 1.00 0.00 100 B -
ValueCastOutPerf 2.3132 ns 0.0547 ns 0.0485 ns 2.52 0.12 138 B -
ValueCastInPerf 7.2275 ns 0.0765 ns 0.0679 ns 7.87 0.30 115 B -
UnionValueAsPerf 8.6285 ns 0.1116 ns 0.1044 ns 9.40 0.35 70 B -
UnionCaseInPerf 6.4480 ns 0.0680 ns 0.0567 ns 7.01 0.28 70 B -

I think my weakness is that it was not created from a constructor, nor was it read-only

@Cricle
Copy link
Author

Cricle commented Dec 15, 2023

But I try to benchmark modifiable and read-only struct, the result shocked me a lot. But as far as I know, read-only structures will be optimized by JIT, and the result should be that read-only structures are better than mutable ones.

 [MemoryDiagnoser]
 public class NewAndSet
 {
     [Benchmark(Baseline =true)]
     public ReadonlyNew FromReadonlyNew()
     {
         return new ReadonlyNew(42);
     }
     [Benchmark]
     public Modifyable FromModifyable()
     {
         Modifyable n = default;
         n.val = 42;
         return n;
     }
     public readonly struct ReadonlyNew
     {
         public ReadonlyNew(int value)
         {
             Value = value;
         }

         public int Value { get; }
     }
     public struct Modifyable
     {
         public int val;

         public int Value
         {
             get => val;
             set => val = value;
         }
     }
 }

The result


BenchmarkDotNet v0.13.11, Windows 10 (10.0.19045.2006/22H2/2022Update)
AMD Ryzen 7 5800H with Radeon Graphics, 1 CPU, 16 logical and 8 physical cores
.NET SDK 8.0.100
  [Host]   : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
  AOT      : .NET 8.0.0, X64 NativeAOT AVX2
  ShortRun : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2

Platform=X64  Server=True  IterationCount=3  
LaunchCount=1  WarmupCount=3  

Method Job Runtime Mean Error StdDev Median Ratio RatioSD Allocated Alloc Ratio
FromReadonlyNew AOT NativeAOT 8.0 0.0495 ns 0.7928 ns 0.0435 ns 0.0670 ns ? ? - ?
FromModifyable AOT NativeAOT 8.0 0.0000 ns 0.0000 ns 0.0000 ns 0.0000 ns ? ? - ?
FromReadonlyNew ShortRun .NET 8.0 0.0119 ns 0.3760 ns 0.0206 ns 0.0000 ns ? ? - ?
FromModifyable ShortRun .NET 8.0 0.0000 ns 0.0000 ns 0.0000 ns 0.0000 ns ? ? - ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant