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

Cleaning up and adding more benchmarks. #983

Merged
merged 4 commits into from
Dec 12, 2020

Conversation

stebet
Copy link
Contributor

@stebet stebet commented Dec 9, 2020

Proposed Changes

Cleaning up the BenchmarkDotNet benchmarks and adding more so we have a better overview and impact of changes made to anything that has to do with (de)serialization of RabbitMQ primitives.

  • I Put all the method benchmarks into one benchmark file for better overview and comparison purposes.
  • Added benchmarks for WireFormatting primitives (int, byte, uint etc.)
  • Added benchmarks for data types (arrays, dictionaries, strings).
  • Added a net48 target for the benchmarks as well.

Types of Changes

  • Bug fix (non-breaking change which fixes issue #NNNN)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause an observable behavior change in existing systems)
  • Documentation improvements (corrections, new content, etc)
  • Cosmetic change (whitespace, formatting, etc)

Checklist

  • I have read the CONTRIBUTING.md document
  • I have signed the CA (see https://cla.pivotal.io/sign/rabbitmq)
  • All tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)
  • Any dependent changes have been merged and published in related repositories

@stebet
Copy link
Contributor Author

stebet commented Dec 9, 2020

As an FYI, here are the current results of this benchmark output on my machine:

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.20270
Intel Core i7-10700 CPU 2.90GHz, 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=5.0.101
  [Host]        : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT
  .NET 4.8      : .NET Framework 4.8 (4.8.4261.0), X64 RyuJIT
  .NET Core 3.1 : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT
Method Runtime Mean Error StdDev Gen 0 Gen 1 Gen 2 Allocated Code Size
DecimalRead .NET 4.8 21.939 ns 0.1721 ns 0.1526 ns - - - - 781 B
DecimalWrite .NET 4.8 29.016 ns 0.0880 ns 0.0735 ns 0.0063 - - 40 B 686 B
LongRead .NET 4.8 10.703 ns 0.1090 ns 0.0851 ns - - - - 440 B
LongWrite .NET 4.8 11.143 ns 0.0680 ns 0.0636 ns - - - - 459 B
LonglongRead .NET 4.8 10.692 ns 0.0393 ns 0.0348 ns - - - - 441 B
LonglongWrite .NET 4.8 11.222 ns 0.1309 ns 0.1224 ns - - - - 466 B
ShortRead .NET 4.8 10.715 ns 0.0718 ns 0.0636 ns - - - - 441 B
ShortWrite .NET 4.8 11.012 ns 0.0536 ns 0.0447 ns - - - - 458 B
TimestampRead .NET 4.8 10.697 ns 0.0474 ns 0.0421 ns - - - - 441 B
TimestampWrite .NET 4.8 12.385 ns 0.0542 ns 0.0423 ns - - - - 545 B
DecimalRead .NET Core 3.1 5.785 ns 0.0151 ns 0.0133 ns - - - - 449 B
DecimalWrite .NET Core 3.1 14.726 ns 0.2515 ns 0.2353 ns 0.0048 - - 40 B 300 B
LongRead .NET Core 3.1 1.302 ns 0.0213 ns 0.0199 ns - - - - 150 B
LongWrite .NET Core 3.1 1.262 ns 0.0101 ns 0.0089 ns - - - - 150 B
LonglongRead .NET Core 3.1 1.294 ns 0.0086 ns 0.0067 ns - - - - 151 B
LonglongWrite .NET Core 3.1 1.301 ns 0.0189 ns 0.0158 ns - - - - 156 B
ShortRead .NET Core 3.1 1.294 ns 0.0109 ns 0.0097 ns - - - - 151 B
ShortWrite .NET Core 3.1 1.754 ns 0.0113 ns 0.0089 ns - - - - 151 B
TimestampRead .NET Core 3.1 1.307 ns 0.0171 ns 0.0152 ns - - - - 151 B
TimestampWrite .NET Core 3.1 1.515 ns 0.0168 ns 0.0157 ns - - - - 158 B
Method Runtime Mean Error StdDev Gen 0 Gen 1 Gen 2 Allocated Code Size
ArrayReadEmpty .NET 4.8 22.820 ns 0.4441 ns 0.4361 ns 0.0063 - - 40 B 672 B
ArrayReadPopulated .NET 4.8 137.263 ns 0.2047 ns 0.1710 ns 0.0343 - - 217 B 672 B
ArrayWriteEmpty .NET 4.8 20.649 ns 0.0291 ns 0.0227 ns - - - - 795 B
ArrayWritePopulated .NET 4.8 142.924 ns 0.8935 ns 0.7461 ns 0.0062 - - 40 B 795 B
TableReadEmpty .NET 4.8 19.544 ns 0.0570 ns 0.0505 ns - - - - 999 B
TableReadPopulated .NET 4.8 863.653 ns 2.5798 ns 2.2870 ns 0.2222 0.0010 - 1404 B 1002 B
TableWriteEmpty .NET 4.8 21.676 ns 0.2943 ns 0.2458 ns - - - - 1505 B
TableWritePopulated .NET 4.8 666.625 ns 3.1778 ns 2.6536 ns 0.0257 - - 168 B 1505 B
LongstrReadEmpty .NET 4.8 18.582 ns 0.1331 ns 0.1180 ns - - - - 668 B
LongstrReadPopulated .NET 4.8 319.274 ns 2.2690 ns 2.0114 ns 0.6561 - - 4134 B 668 B
LongstrWriteEmpty .NET 4.8 26.209 ns 0.0735 ns 0.0651 ns - - - - 846 B
LongstrWritePopulated .NET 4.8 1,730.893 ns 6.9724 ns 6.5220 ns - - - - 840 B
ShortstrReadEmpty .NET 4.8 9.773 ns 0.0826 ns 0.0732 ns - - - - 830 B
ShortstrReadPopulated .NET 4.8 178.406 ns 0.6001 ns 0.5613 ns 0.0854 - - 538 B 866 B
ShortstrWriteEmpty .NET 4.8 27.042 ns 0.1473 ns 0.1306 ns - - - - 719 B
ShortstrWritePopulated .NET 4.8 144.082 ns 0.8153 ns 0.7626 ns - - - - 715 B
ArrayReadEmpty .NET Core 3.1 12.401 ns 0.0976 ns 0.0865 ns 0.0038 - - 32 B 408 B
ArrayReadPopulated .NET Core 3.1 96.808 ns 0.3429 ns 0.3208 ns 0.0248 - - 208 B 408 B
ArrayWriteEmpty .NET Core 3.1 4.587 ns 0.0215 ns 0.0201 ns - - - - 413 B
ArrayWritePopulated .NET Core 3.1 82.959 ns 0.4525 ns 0.4233 ns 0.0048 - - 40 B 413 B
TableReadEmpty .NET Core 3.1 9.277 ns 0.0173 ns 0.0135 ns - - - - 645 B
TableReadPopulated .NET Core 3.1 752.980 ns 3.8807 ns 3.2406 ns 0.1612 - - 1352 B 648 B
TableWriteEmpty .NET Core 3.1 11.404 ns 0.0356 ns 0.0333 ns - - - - 1041 B
TableWritePopulated .NET Core 3.1 422.034 ns 1.4816 ns 1.1567 ns 0.0200 - - 168 B 1041 B
LongstrReadEmpty .NET Core 3.1 3.173 ns 0.0597 ns 0.0529 ns - - - - 315 B
LongstrReadPopulated .NET Core 3.1 222.098 ns 4.3371 ns 4.9946 ns 0.4923 - - 4120 B 315 B
LongstrWriteEmpty .NET Core 3.1 9.726 ns 0.0399 ns 0.0354 ns - - - - 516 B
LongstrWritePopulated .NET Core 3.1 219.733 ns 0.7856 ns 0.6964 ns - - - - 512 B
ShortstrReadEmpty .NET Core 3.1 1.524 ns 0.0073 ns 0.0061 ns - - - - 248 B
ShortstrReadPopulated .NET Core 3.1 57.677 ns 1.1032 ns 1.1329 ns 0.0641 - - 536 B 508 B
ShortstrWriteEmpty .NET Core 3.1 11.495 ns 0.0496 ns 0.0414 ns - - - - 392 B
ShortstrWritePopulated .NET Core 3.1 25.018 ns 0.4949 ns 0.5083 ns - - - - 388 B
Method Runtime Mean Error StdDev Median Gen 0 Gen 1 Gen 2 Allocated Code Size
BasicAckRead .NET 4.8 22.512 ns 0.1782 ns 0.1488 ns 22.527 ns 0.0051 - - 32 B 676 B
BasicAckWrite .NET 4.8 21.315 ns 0.0615 ns 0.0545 ns 21.305 ns - - - - 689 B
BasicDeliverRead .NET 4.8 32.278 ns 0.4230 ns 0.3532 ns 32.202 ns 0.0089 - - 56 B 1475 B
BasicDeliverWrite .NET 4.8 79.532 ns 0.2814 ns 0.2495 ns 79.463 ns - - - - 873 B
BasicPropertiesRead .NET 4.8 108.924 ns 0.4782 ns 0.3994 ns 108.755 ns 0.0318 - - 201 B 6603 B
BasicPropertiesWrite .NET 4.8 76.225 ns 1.1911 ns 1.1698 ns 75.817 ns - - - - 1991 B
ChannelCloseRead .NET 4.8 27.916 ns 0.2079 ns 0.1843 ns 27.899 ns 0.0051 - - 32 B 1049 B
ChannelCloseWrite .NET 4.8 40.392 ns 0.3391 ns 0.3172 ns 40.225 ns - - - - 816 B
BasicAckRead .NET Core 3.1 4.796 ns 0.1006 ns 0.0941 ns 4.768 ns 0.0038 - - 32 B 260 B
BasicAckWrite .NET Core 3.1 3.324 ns 0.0173 ns 0.0144 ns 3.321 ns - - - - 256 B
BasicDeliverRead .NET Core 3.1 13.006 ns 0.1830 ns 0.1712 ns 12.977 ns 0.0067 - - 56 B 935 B
BasicDeliverWrite .NET Core 3.1 36.468 ns 0.2432 ns 0.2156 ns 36.454 ns - - - - 438 B
BasicPropertiesRead .NET Core 3.1 70.037 ns 1.2143 ns 1.0140 ns 69.550 ns 0.0229 - - 192 B 3461 B
BasicPropertiesWrite .NET Core 3.1 34.849 ns 0.3061 ns 0.2713 ns 34.729 ns - - - - 1433 B
ChannelCloseRead .NET Core 3.1 8.378 ns 0.0411 ns 0.0364 ns 8.365 ns 0.0038 - - 32 B 582 B
ChannelCloseWrite .NET Core 3.1 15.743 ns 0.2899 ns 0.4249 ns 15.524 ns - - - - 392 B

@bollhals
Copy link
Contributor

bollhals commented Dec 9, 2020

I like the comparability, but how do you run a single benchmark out of them? (e.g. if you improve the decimal deserialization, I'm only interested in that one)

@bollhals
Copy link
Contributor

bollhals commented Dec 9, 2020

ArrayReadEmpty we could improve for size 0 (return Array.Empty as it implements IList or return null as we do for table/dictionary)

@stebet
Copy link
Contributor Author

stebet commented Dec 9, 2020

I like the comparability, but how do you run a single benchmark out of them? (e.g. if you improve the decimal deserialization, I'm only interested in that one)

Usually if I run specific ones I like to just comment them out temporarily. When doing broader changes like optimizing something that might impact all methods for example, I'd like an easy way to run all of them. All feedback welcome :)

@bollhals
Copy link
Contributor

bollhals commented Dec 9, 2020

Either way works I guess, It just takes some getting used to.

Regarding the multiple frameworks:
While improving something I usually just run a short job on one framework to test (as otherwise it just takes too long and it's accurate enough while developing. How could we keep this shortcut?

Is it possible to have another Program.cs which only executes short runs on one framework and your changed one for when you need a "full picture". Switching from one to the other should be possible AFAIK from within VS (not sure about VS Code).

@stebet
Copy link
Contributor Author

stebet commented Dec 9, 2020

Either way works I guess, It just takes some getting used to.

Regarding the multiple frameworks:
While improving something I usually just run a short job on one framework to test (as otherwise it just takes too long and it's accurate enough while developing. How could we keep this shortcut?

Is it possible to have another Program.cs which only executes short runs on one framework and your changed one for when you need a "full picture". Switching from one to the other should be possible AFAIK from within VS (not sure about VS Code).

I split them up a bit. You can now run them individually (per-datatype or per-method). You can also type * to run all of them. By default it then runs them for both .NET 4.8 and .NET Core 3.1. The default job also runs allocation and disassembly dignosers.
image

@michaelklishin michaelklishin merged commit dbc9853 into rabbitmq:master Dec 12, 2020
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.

3 participants