Skip to content

Investigate Clone performance #4863

Open
luizfbicalho wants to merge 8 commits into
MarimerLLC:mainfrom
luizfbicalho:feature/cloner-update-performance
Open

Investigate Clone performance #4863
luizfbicalho wants to merge 8 commits into
MarimerLLC:mainfrom
luizfbicalho:feature/cloner-update-performance

Conversation

@luizfbicalho

Copy link
Copy Markdown
Contributor

PR to add the performance improvements to
clone method

#4272


BenchmarkDotNet v0.15.8, Windows 10 (10.0.19045.6466/22H2/2022Update) (Hyper-V)
Intel Core i7-10750H CPU 2.60GHz (Max: 2.59GHz), 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.300
  [Host]               : .NET 10.0.8 (10.0.8, 10.0.826.23019), X64 RyuJIT x86-64-v3
  .NET 10.0            : .NET 10.0.8 (10.0.8, 10.0.826.23019), X64 RyuJIT x86-64-v3
  .NET 8.0             : .NET 8.0.27 (8.0.27, 8.0.2726.22922), X64 RyuJIT x86-64-v3
  .NET 9.0             : .NET 9.0.16 (9.0.16, 9.0.1626.22923), X64 RyuJIT x86-64-v3
  .NET Framework 4.6.2 : .NET Framework 4.8.1 (4.8.9310.0), X64 RyuJIT VectorSize=256
  .NET Framework 4.7.2 : .NET Framework 4.8.1 (4.8.9310.0), X64 RyuJIT VectorSize=256
  .NET Framework 4.8   : .NET Framework 4.8.1 (4.8.9310.0), X64 RyuJIT VectorSize=256


Method Job Runtime Mean Error StdDev Median Ratio RatioSD Gen0 Gen1 Gen2 Allocated Alloc Ratio
FetchAndSerialize .NET 10.0 .NET 10.0 159.9 ms 8.21 ms 24.09 ms 160.1 ms 1.02 0.22 - - - 116.46 MB 1.00
FetchAndCloneInternal .NET 10.0 .NET 10.0 111.2 ms 2.22 ms 5.93 ms 109.9 ms 0.71 0.12 500.0000 - - 69.24 MB 0.59
FetchAndSerialize .NET 8.0 .NET 8.0 205.0 ms 9.34 ms 27.54 ms 214.5 ms 1.02 0.21 2000.0000 1000.0000 - 130.33 MB 1.00
FetchAndCloneInternal .NET 8.0 .NET 8.0 158.7 ms 5.37 ms 15.57 ms 159.5 ms 0.79 0.14 500.0000 - - 83.11 MB 0.64
FetchAndSerialize .NET 9.0 .NET 9.0 207.7 ms 12.87 ms 36.51 ms 215.9 ms 1.03 0.27 2000.0000 1000.0000 - 129.79 MB 1.00
FetchAndCloneInternal .NET 9.0 .NET 9.0 135.9 ms 5.46 ms 16.10 ms 135.2 ms 0.68 0.16 1000.0000 500.0000 - 82.57 MB 0.64
FetchAndSerialize .NET Framework 4.6.2 .NET Framework 4.6.2 529.1 ms 10.55 ms 17.34 ms 526.8 ms 1.00 0.05 20000.0000 8000.0000 1000.0000 126.85 MB 1.00
FetchAndCloneInternal .NET Framework 4.6.2 .NET Framework 4.6.2 356.0 ms 8.72 ms 25.03 ms 352.2 ms 0.67 0.05 13000.0000 5000.0000 1000.0000 79.72 MB 0.63
FetchAndSerialize .NET Framework 4.7.2 .NET Framework 4.7.2 489.3 ms 9.75 ms 18.79 ms 486.0 ms 1.00 0.05 20000.0000 8000.0000 1000.0000 126.85 MB 1.00
FetchAndCloneInternal .NET Framework 4.7.2 .NET Framework 4.7.2 337.0 ms 6.72 ms 8.97 ms 337.5 ms 0.69 0.03 13000.0000 5000.0000 1000.0000 79.72 MB 0.63
FetchAndSerialize .NET Framework 4.8 .NET Framework 4.8 482.8 ms 9.47 ms 13.59 ms 481.0 ms 1.00 0.04 20000.0000 8000.0000 1000.0000 126.85 MB 1.00
FetchAndCloneInternal .NET Framework 4.8 .NET Framework 4.8 334.8 ms 6.66 ms 6.23 ms 336.6 ms 0.69 0.02 13000.0000 5000.0000 1000.0000 79.65 MB 0.63

Introduced the ISerializationCloner interface to support efficient object cloning via serialization. Updated MobileFormatter to implement this interface and provided a Clone method using DTO serialization. Refactored ObjectCloner to use the new interface when available, with fallback to the previous approach. Removed unused usings in MobileFormatter.cs.
Removed the <ItemGroup> that updated Nerdbank.GitVersioning to version 3.9.50 in Csla.Benchmarks.csproj. No other changes were made.

@StefanOssendorf StefanOssendorf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. I'll have to take a deeper look in the next days but skimming through the test classes you are going all out :D

Comment thread Source/Csla.Benchmarks/PerformanceCloner/PerformanceClonerBenchmark.cs Outdated
Comment thread Source/Csla.Benchmarks/PerformanceCloner/PerformanceClonerBenchmark.cs Outdated

@StefanOssendorf StefanOssendorf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being this late to my review.
I run your benchmarks on my computer only for the .net Runtimes. I don't have Windows available.

Nevertheless the results look great!

Image

The only thing is I'm not happy about the implementation chain. So I added a comment there.

Comment thread Source/Csla.Benchmarks/PerformanceCloner/PerformanceClonerBenchmark.cs Outdated
Comment thread Source/Csla.Benchmarks/PerformanceCloner/PerformanceClonerBenchmark.cs Outdated
/// Defines an object that can clone objects via serialization of
/// object graphs with improved performance.
/// </summary>
public interface ISerializationCloner : ISerializationFormatter

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this implementation chain is not right.
A Cloner is not a SerializationFormatter.
So I think it would be better to make it an independent interface and MobileFormatter implements both. Your check in the ObjectCloner would still work and the concepts wouldn't be mixed.

Maybe @rockfordlhotka has an opinion on that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about that, and for me it is a formatter with more features, and not another service, if I remove the inheritance from ISerialization formatter I need to change the code to look for 2 different services in the service provider

Changed FetchAndSerialize and FetchAndCloneInternal from async Task<object?> to synchronous object? methods in PerformanceClonerBenchmark.cs, removing async/await usage.
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

Successfully merging this pull request may close these issues.

2 participants