EfficientDynamoDb icon indicating copy to clipboard operation
EfficientDynamoDb copied to clipboard

Upgrade .NET version and harmonize versions of referenced packages

Open devtekve opened this issue 1 year ago • 3 comments

This commit makes several changes to the .NET projects and their dependencies. The main changes include upgrading the projects to target newer versions of .NET (.NET 6.0, 7.0 and 8.0), and harmonize versions of referenced packages.

The package versions are now based on the target framework. The git diff shows the removal and addition of PackageReference tags that ensure packages have different versions based on the targeted framework. For example, Microsoft.NET.Test.Sdk is upgraded from 16.9.4 to 17.9.0 if the target framework is not net6.0.

In addition, the commit modifies the projects to produce an executable as the output type instead of a class library and removes constructors in exception classes which are obsolete from .net8 onwards (https://github.com/dotnet/docs/issues/34893).

Finally, some refactoring is done to comply with the latest .net requirements regarding value and ref types.

Overall, this commit ensures the projects align with the latest .NET platform, benefiting from performance improvements and other advancements, while keeping the project dependencies clean and consistent.

Benchmark

.net7.0

BenchmarkDotNet v0.13.12, macOS Sonoma 14.3.1 (23D60) [Darwin 23.3.0]
Apple M1 Pro, 1 CPU, 10 logical and 10 physical cores
.NET SDK 8.0.201
  [Host]     : .NET 7.0.16 (7.0.1624.6629), Arm64 RyuJIT AdvSIMD
  DefaultJob : .NET 7.0.16 (7.0.1624.6629), Arm64 RyuJIT AdvSIMD


| Method            | EntitiesCount | Mean         | Error      | StdDev     | Gen0      | Gen1      | Gen2     | Allocated   |
|------------------ |-------------- |-------------:|-----------:|-----------:|----------:|----------:|---------:|------------:|
| EfficientDynamoDb | 10            |     33.07 us |   0.384 us |   0.359 us |    2.8076 |         - |        - |    17.23 KB |
| aws-sdk-net       | 10            |    309.88 us |   2.384 us |   2.113 us |   51.2695 |   13.1836 |        - |   315.54 KB |
| EfficientDynamoDb | 100           |    247.07 us |   3.939 us |   3.684 us |   19.5313 |    3.9063 |        - |   119.89 KB |
| aws-sdk-net       | 100           |  3,334.25 us |  47.241 us |  41.878 us |  480.4688 |  210.9375 |        - |  2958.24 KB |
| EfficientDynamoDb | 1000          |  2,468.43 us |  16.851 us |  15.762 us |  183.5938 |   89.8438 |        - |  1146.49 KB |
| aws-sdk-net       | 1000          | 48,140.56 us | 700.329 us | 620.823 us | 5090.9091 | 1363.6364 | 454.5455 | 29379.18 KB |

.net8.0

BenchmarkDotNet v0.13.12, macOS Sonoma 14.3.1 (23D60) [Darwin 23.3.0]
Apple M1 Pro, 1 CPU, 10 logical and 10 physical cores
.NET SDK 8.0.201
  [Host]     : .NET 8.0.2 (8.0.224.6711), Arm64 RyuJIT AdvSIMD
  DefaultJob : .NET 8.0.2 (8.0.224.6711), Arm64 RyuJIT AdvSIMD


| Method            | EntitiesCount | Mean         | Error      | StdDev     | Gen0      | Gen1      | Gen2      | Allocated   |
|------------------ |-------------- |-------------:|-----------:|-----------:|----------:|----------:|----------:|------------:|
| EfficientDynamoDb | 10            |     25.87 us |   0.252 us |   0.211 us |    2.7771 |    0.0916 |         - |    17.17 KB |
| aws-sdk-net       | 10            |    207.30 us |   3.084 us |   2.885 us |   51.2695 |   13.1836 |         - |   314.92 KB |
| EfficientDynamoDb | 100           |    187.08 us |   1.162 us |   1.030 us |   19.5313 |    0.2441 |         - |   119.84 KB |
| aws-sdk-net       | 100           |  2,459.85 us |  48.444 us | 119.743 us |  476.5625 |  234.3750 |         - |  2956.09 KB |
| EfficientDynamoDb | 1000          |  2,107.96 us |  41.388 us |  66.833 us |  183.5938 |   89.8438 |         - |  1146.55 KB |
| aws-sdk-net       | 1000          | 40,097.83 us | 494.365 us | 412.817 us | 4833.3333 | 1250.0000 | 1083.3333 | 29341.09 KB |

Note:

I don't have available a proper x86 setup where I could run the benchmark for the older dotnet versions, so I can't provide a proper comparison between current .netstandard2.1 and latest .net8. The improvement is still in line with the comparison against aws sdk, which also sees improvements by bumping the framework. So I see an overall performance gain.

If anyone is able to, can you please run the benchmarks on your system to see how it compares against the current version used? thank you :)

devtekve avatar May 10 '24 10:05 devtekve

Thanks for submitting the PR @devtekve. Changing target version is a breaking change. I'm ok with doing that but we'll need to think about all breaking changes we want to make and bundle them into a single release. And before doing an upgrade I would like to release already implemented features to make sure we don't block anyone waiting for them.

And couple of notes about the update itself:

  1. I don't want to support multiple targets and deal with compiler directives. In my experience they are usually a pain to support and I'd rather pick one target.
  2. .NET 7 goes out of support in several days on May 14th. .NET 6's end of support is in November 2024, so it only has 6 months of lifetime. Taking these timelines into account I think it make sense to only support .NET 8 going forward and drop all previous versions.
  3. Performance benefits you've observed in your benchmarks are achievable without updating the library's target framework. If your code runs on .NET 8 you'll get the runtime benefits regardless the library version. You can test it using the benchmarkdotnet. To do it, add the [SimpleJob(RuntimeMoniker.Net80)] and [SimpleJob(RuntimeMoniker.Net70)] (or more other) attributes to the class that contains benchmarks without changing the target version of EfficientDynamoDb. You may need to update the BenchmarkDotNet version to get enum values for latest runtimes. An actual performance benefit from changing the target framework can come from:
    1. Using newer more performant APIs from latest .NET versions
    2. If any of the libraries we use in our code uses the newer faster API that's only available in latest .NET versions. This is most likely the case with System.Text.Json as it was improved quite a lot recently.

Overall, I think we need to bump the version to .net 8 but I'm not sure that right now is the best moment to do it. If you're up to it, let's leave your PR open and update it to only target .NET 8. And we can merge it after doing all necessary preparations.

firenero avatar May 11 '24 01:05 firenero

Definitely up for it. Only reason I added the multiple frameworks was to keep it somewhat backwards compatible. But I'd simply target .net8.0 as it's the latest LTS.

Also I am agree it's a breaking change, but in the other hand, the other runtimes are no longer supported. (Well, .netstandard2.1 is, but I found one bug regarding passing value types as references... latest .net8 is against it and yet .netstandard2.1 seems happy with it )

We can leave it open and polish it, get it ready and properly flagged as breaking change... to be honest, none of the PRs I made had the expectation of being merged as is, I expected some discussion since I am brand new to the project and still getting the hang of it but I'm really loving what you've done here hahahah

devtekve avatar May 11 '24 02:05 devtekve

@firenero I've updated the PR removing many whitespaces changes on the csprojs, and removed the multiple .net frameworks from the targets, leaving only .net8

devtekve avatar May 11 '24 13:05 devtekve

Closing this PR because .net8 migration was implemented in a more lightweight #263.

firenero avatar May 31 '25 13:05 firenero