-
Notifications
You must be signed in to change notification settings - Fork 386
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
Enum boxing optimizations (UnitKey) #1507
base: release/v6
Are you sure you want to change the base?
Conversation
- introduce the UnitKey struct as a replacement for the conversions from TUnit to Enum - re-map the UnitAbbreviationCache using the UnitKey for the concurrent dictionary - remove all Convert.ToInt32(..) calls - optimize the QuantityInfoLookup collections - refactored some of the Quantity/UnitConverter code (using the UnitParser/UnitAbbreviationsCache) - added some tests and benchmarks covering the new modifications
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before:
Method | Job | Runtime | NbAbbreviations | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|---|
FromMassString | .NET 8.0 | .NET 8.0 | 1000 | 29.54 ms | 0.443 ms | 0.415 ms | 1.00 | 0.02 | 2833.3333 | - | 47.57 MB | 1.00 |
FromVolumeUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 66.68 ms | 1.132 ms | 1.004 ms | 2.26 | 0.04 | 5750.0000 | 500.0000 | 93.34 MB | 1.96 |
FromPressureUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 69.09 ms | 1.319 ms | 1.234 ms | 2.34 | 0.05 | 6000.0000 | 333.3333 | 100.31 MB | 2.11 |
FromVolumeFlowUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 133.05 ms | 2.236 ms | 2.092 ms | 4.51 | 0.09 | 12000.0000 | 1000.0000 | 200.47 MB | 4.21 |
FromMassString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 65.22 ms | 0.542 ms | 0.507 ms | 1.00 | 0.01 | 13000.0000 | 500.0000 | 78.08 MB | 1.00 |
FromVolumeUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 135.02 ms | 1.001 ms | 0.937 ms | 2.07 | 0.02 | 25250.0000 | 1500.0000 | 152.05 MB | 1.95 |
FromPressureUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 123.84 ms | 1.260 ms | 1.117 ms | 1.90 | 0.02 | 23000.0000 | 1250.0000 | 139.26 MB | 1.78 |
FromVolumeFlowUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 211.69 ms | 2.007 ms | 1.779 ms | 3.25 | 0.04 | 44333.3333 | 5000.0000 | 267.62 MB | 3.43 |
After:
Method | Job | Runtime | NbAbbreviations | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|---|
FromMassString | .NET 8.0 | .NET 8.0 | 1000 | 19.25 ms | 0.364 ms | 0.341 ms | 1.00 | 0.02 | 2406.2500 | 93.7500 | 38.85 MB | 1.00 |
FromVolumeUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 42.83 ms | 0.779 ms | 0.691 ms | 2.22 | 0.05 | 4800.0000 | 400.0000 | 77.39 MB | 1.99 |
FromPressureUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 47.75 ms | 0.742 ms | 0.694 ms | 2.48 | 0.05 | 5250.0000 | 500.0000 | 85.49 MB | 2.20 |
FromVolumeFlowUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 92.35 ms | 1.824 ms | 1.873 ms | 4.80 | 0.12 | 10500.0000 | 1500.0000 | 174 MB | 4.48 |
FromMassString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 29.24 ms | 0.142 ms | 0.119 ms | 1.00 | 0.01 | 10031.2500 | 437.5000 | 60.37 MB | 1.00 |
FromVolumeUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 59.12 ms | 0.530 ms | 0.470 ms | 2.02 | 0.02 | 19555.5556 | 1333.3333 | 117.49 MB | 1.95 |
FromPressureUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 54.80 ms | 0.732 ms | 0.685 ms | 1.87 | 0.02 | 17555.5556 | 1111.1111 | 105.38 MB | 1.75 |
FromVolumeFlowUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 98.17 ms | 0.625 ms | 0.554 ms | 3.36 | 0.02 | 35000.0000 | 4333.3333 | 211.02 MB | 3.50 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before:
Method | Job | Runtime | NbAbbreviations | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|
FromMassUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 482.2 ms | 4.45 ms | 4.16 ms | 1.00 | 0.01 | 28000.0000 | 450.85 MB | 1.00 |
FromVolumeUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 476.1 ms | 8.37 ms | 7.83 ms | 0.99 | 0.02 | 28000.0000 | 450.85 MB | 1.00 |
FromPressureUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 480.2 ms | 8.78 ms | 8.21 ms | 1.00 | 0.02 | 28000.0000 | 450.85 MB | 1.00 |
FromVolumeFlowUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 479.6 ms | 3.31 ms | 3.10 ms | 0.99 | 0.01 | 28000.0000 | 450.85 MB | 1.00 |
FromMassUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 1,391.4 ms | 2.97 ms | 2.78 ms | 1.00 | 0.00 | 129000.0000 | 779.46 MB | 1.00 |
FromVolumeUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 1,392.8 ms | 2.08 ms | 1.84 ms | 1.00 | 0.00 | 129000.0000 | 779.46 MB | 1.00 |
FromPressureUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 1,397.4 ms | 3.15 ms | 2.95 ms | 1.00 | 0.00 | 129000.0000 | 779.46 MB | 1.00 |
FromVolumeFlowUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 1,406.1 ms | 3.66 ms | 3.42 ms | 1.01 | 0.00 | 129000.0000 | 779.46 MB | 1.00 |
After:
Method | Job | Runtime | NbAbbreviations | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|
FromMassUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 104.8 ms | 1.00 ms | 0.94 ms | 1.00 | 0.01 | 14400.0000 | 230.67 MB | 1.00 |
FromVolumeUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 104.1 ms | 2.03 ms | 2.25 ms | 0.99 | 0.02 | 14400.0000 | 230.67 MB | 1.00 |
FromPressureUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 103.6 ms | 2.01 ms | 2.15 ms | 0.99 | 0.02 | 14400.0000 | 230.67 MB | 1.00 |
FromVolumeFlowUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 103.4 ms | 1.08 ms | 0.95 ms | 0.99 | 0.01 | 14400.0000 | 230.67 MB | 1.00 |
FromMassUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 199.5 ms | 2.17 ms | 2.03 ms | 1.00 | 0.01 | 38333.3333 | 231.69 MB | 1.00 |
FromVolumeUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 200.9 ms | 2.26 ms | 2.11 ms | 1.01 | 0.01 | 38333.3333 | 231.69 MB | 1.00 |
FromPressureUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 201.6 ms | 1.68 ms | 1.49 ms | 1.01 | 0.01 | 38333.3333 | 231.69 MB | 1.00 |
FromVolumeFlowUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 199.3 ms | 2.26 ms | 2.12 ms | 1.00 | 0.01 | 38333.3333 | 231.69 MB | 1.00 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before:
Method | Job | Runtime | NbAbbreviations | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|---|
FromMassUnitName | .NET 8.0 | .NET 8.0 | 1000 | 453.0 μs | 8.92 μs | 9.55 μs | 1.00 | 0.03 | 31.7383 | - | 523.49 KB | 1.00 |
FromVolumeUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 715.0 μs | 2.71 μs | 2.40 μs | 1.58 | 0.03 | 44.9219 | - | 734.53 KB | 1.40 |
FromPressureUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 601.0 μs | 3.31 μs | 2.93 μs | 1.33 | 0.03 | 41.9922 | - | 695.47 KB | 1.33 |
FromVolumeFlowUnitAbbreviation | .NET 8.0 | .NET 8.0 | 1000 | 825.9 μs | 13.83 μs | 12.26 μs | 1.82 | 0.05 | 54.6875 | 0.9766 | 898.74 KB | 1.72 |
FromMassUnitName | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 779.2 μs | 4.34 μs | 4.06 μs | 1.00 | 0.01 | 103.5156 | - | 638.86 KB | 1.00 |
FromVolumeUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 1,257.2 μs | 11.20 μs | 10.47 μs | 1.61 | 0.02 | 138.6719 | - | 861.88 KB | 1.35 |
FromPressureUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 1,044.7 μs | 13.83 μs | 12.93 μs | 1.34 | 0.02 | 136.7188 | - | 846.97 KB | 1.33 |
FromVolumeFlowUnitAbbreviation | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 1,446.6 μs | 17.30 μs | 16.18 μs | 1.86 | 0.02 | 169.9219 | - | 1049.27 KB | 1.64 |
After:
Method | Job | Runtime | NbAbbreviations | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|
FromMassUnitName | .NET 8.0 | .NET 8.0 | 1000 | 124.5 μs | 0.94 μs | 0.88 μs | 1.00 | 0.01 | 9.0332 | 148.44 KB | 1.00 |
FromVolumeUnitName | .NET 8.0 | .NET 8.0 | 1000 | 186.9 μs | 1.44 μs | 1.35 μs | 1.50 | 0.01 | 9.0332 | 148.44 KB | 1.00 |
FromPressureUnitName | .NET 8.0 | .NET 8.0 | 1000 | 156.0 μs | 1.22 μs | 1.14 μs | 1.25 | 0.01 | 9.0332 | 148.44 KB | 1.00 |
FromVolumeFlowUnitName | .NET 8.0 | .NET 8.0 | 1000 | 215.1 μs | 1.16 μs | 1.08 μs | 1.73 | 0.01 | 9.0332 | 148.44 KB | 1.00 |
FromMassUnitName | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 190.1 μs | 1.67 μs | 1.56 μs | 1.00 | 0.01 | 24.1699 | 148.88 KB | 1.00 |
FromVolumeUnitName | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 272.5 μs | 2.01 μs | 1.68 μs | 1.43 | 0.01 | 23.9258 | 148.88 KB | 1.00 |
FromPressureUnitName | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 247.6 μs | 2.30 μs | 1.92 μs | 1.30 | 0.01 | 23.9258 | 148.88 KB | 1.00 |
FromVolumeFlowUnitName | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | 343.3 μs | 1.85 μs | 1.64 μs | 1.81 | 0.02 | 23.9258 | 148.88 KB | 1.00 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...must have missed to rename some of these methods..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 03973bf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before:
Method | Job | Runtime | NbConversions | Format | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|---|
MassToUnit | .NET 8.0 | .NET 8.0 | 1000 | A | 218.4 μs | 2.06 μs | 1.82 μs | 1.00 | 0.01 | 18.3105 | 299.32 KB | 1.00 |
VolumeFlowToUnit | .NET 8.0 | .NET 8.0 | 1000 | A | 259.7 μs | 1.56 μs | 1.31 μs | 1.19 | 0.01 | 18.5547 | 303.12 KB | 1.01 |
MassToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | A | 688.3 μs | 6.91 μs | 6.13 μs | 1.00 | 0.01 | 74.2188 | 460.19 KB | 1.00 |
VolumeFlowToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | A | 787.3 μs | 12.25 μs | 11.46 μs | 1.14 | 0.02 | 81.0547 | 498.97 KB | 1.08 |
MassToUnit | .NET 8.0 | .NET 8.0 | 1000 | E | 328.7 μs | 2.78 μs | 2.32 μs | 1.00 | 0.01 | 25.3906 | 417.59 KB | 1.00 |
VolumeFlowToUnit | .NET 8.0 | .NET 8.0 | 1000 | E | 385.6 μs | 3.53 μs | 3.30 μs | 1.17 | 0.01 | 25.8789 | 429.64 KB | 1.03 |
MassToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | E | 1,204.0 μs | 6.33 μs | 5.62 μs | 1.00 | 0.01 | 126.9531 | 781.48 KB | 1.00 |
VolumeFlowToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | E | 1,293.8 μs | 10.65 μs | 9.96 μs | 1.07 | 0.01 | 132.8125 | 825.57 KB | 1.06 |
MassToUnit | .NET 8.0 | .NET 8.0 | 1000 | G | 323.7 μs | 4.11 μs | 3.85 μs | 1.00 | 0.02 | 24.9023 | 408.62 KB | 1.00 |
VolumeFlowToUnit | .NET 8.0 | .NET 8.0 | 1000 | G | 380.4 μs | 3.00 μs | 2.66 μs | 1.18 | 0.02 | 25.3906 | 417.5 KB | 1.02 |
MassToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | G | 1,221.0 μs | 10.35 μs | 9.68 μs | 1.00 | 0.01 | 121.0938 | 751.29 KB | 1.00 |
VolumeFlowToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | G | 1,302.3 μs | 15.53 μs | 13.77 μs | 1.07 | 0.01 | 128.9063 | 798.54 KB | 1.06 |
MassToUnit | .NET 8.0 | .NET 8.0 | 1000 | N | 353.0 μs | 1.31 μs | 1.16 μs | 1.00 | 0.00 | 24.4141 | 403.69 KB | 1.00 |
VolumeFlowToUnit | .NET 8.0 | .NET 8.0 | 1000 | N | 428.3 μs | 3.79 μs | 3.55 μs | 1.21 | 0.01 | 25.3906 | 415.38 KB | 1.03 |
MassToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | N | 1,217.6 μs | 10.66 μs | 9.97 μs | 1.00 | 0.01 | 121.0938 | 750.96 KB | 1.00 |
VolumeFlowToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | N | 1,295.9 μs | 9.27 μs | 8.67 μs | 1.06 | 0.01 | 128.9063 | 795.49 KB | 1.06 |
MassToUnit | .NET 8.0 | .NET 8.0 | 1000 | S | 437.3 μs | 4.77 μs | 4.23 μs | 1.00 | 0.01 | 36.1328 | 596.14 KB | 1.00 |
VolumeFlowToUnit | .NET 8.0 | .NET 8.0 | 1000 | S | 500.5 μs | 4.92 μs | 4.61 μs | 1.14 | 0.01 | 36.1328 | 605.06 KB | 1.01 |
MassToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | S | 1,389.8 μs | 12.66 μs | 11.23 μs | 1.00 | 0.01 | 160.1563 | 986.45 KB | 1.00 |
VolumeFlowToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | S | 1,476.5 μs | 8.74 μs | 7.75 μs | 1.06 | 0.01 | 167.9688 | 1033.87 KB | 1.05 |
After:
Method | Job | Runtime | NbConversions | Format | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MassToString | .NET 8.0 | .NET 8.0 | 1000 | A | 32.53 μs | 0.624 μs | 1.656 μs | 31.90 μs | 1.00 | 0.07 | 8.1177 | 132.81 KB | 1.00 |
VolumeFlowToString | .NET 8.0 | .NET 8.0 | 1000 | A | 33.46 μs | 0.664 μs | 1.604 μs | 33.08 μs | 1.03 | 0.07 | 8.1177 | 132.81 KB | 1.00 |
MassToString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | A | 95.63 μs | 0.780 μs | 0.651 μs | 95.73 μs | 1.00 | 0.01 | 21.6064 | 133.2 KB | 1.00 |
VolumeFlowToString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | A | 121.64 μs | 1.682 μs | 1.574 μs | 121.86 μs | 1.27 | 0.02 | 21.4844 | 133.2 KB | 1.00 |
MassToString | .NET 8.0 | .NET 8.0 | 1000 | E | 136.75 μs | 2.122 μs | 1.984 μs | 136.12 μs | 1.00 | 0.02 | 15.1367 | 251.08 KB | 1.00 |
VolumeFlowToString | .NET 8.0 | .NET 8.0 | 1000 | E | 136.72 μs | 2.512 μs | 2.350 μs | 135.72 μs | 1.00 | 0.02 | 15.8691 | 259.3 KB | 1.03 |
MassToString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | E | 518.30 μs | 5.143 μs | 4.294 μs | 518.16 μs | 1.00 | 0.01 | 73.2422 | 454.38 KB | 1.00 |
VolumeFlowToString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | E | 584.19 μs | 3.707 μs | 3.467 μs | 584.19 μs | 1.13 | 0.01 | 74.2188 | 459.44 KB | 1.01 |
MassToString | .NET 8.0 | .NET 8.0 | 1000 | G | 138.71 μs | 2.147 μs | 2.008 μs | 138.01 μs | 1.00 | 0.02 | 14.6484 | 242.1 KB | 1.00 |
VolumeFlowToString | .NET 8.0 | .NET 8.0 | 1000 | G | 135.84 μs | 1.515 μs | 1.343 μs | 135.90 μs | 0.98 | 0.02 | 14.8926 | 247.16 KB | 1.02 |
MassToString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | G | 513.74 μs | 5.896 μs | 5.515 μs | 511.84 μs | 1.00 | 0.01 | 68.3594 | 424.2 KB | 1.00 |
VolumeFlowToString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | G | 530.12 μs | 4.532 μs | 4.018 μs | 529.22 μs | 1.03 | 0.01 | 70.3125 | 432.44 KB | 1.02 |
MassToString | .NET 8.0 | .NET 8.0 | 1000 | N | 148.71 μs | 1.951 μs | 1.825 μs | 148.45 μs | 1.00 | 0.02 | 14.4043 | 237.18 KB | 1.00 |
VolumeFlowToString | .NET 8.0 | .NET 8.0 | 1000 | N | 148.93 μs | 1.158 μs | 1.026 μs | 148.83 μs | 1.00 | 0.01 | 14.8926 | 245.03 KB | 1.03 |
MassToString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | N | 511.71 μs | 5.712 μs | 5.343 μs | 511.12 μs | 1.00 | 0.01 | 68.3594 | 423.86 KB | 1.00 |
VolumeFlowToString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | N | 537.45 μs | 2.468 μs | 1.927 μs | 537.13 μs | 1.05 | 0.01 | 69.3359 | 429.4 KB | 1.01 |
MassToString | .NET 8.0 | .NET 8.0 | 1000 | S | 232.09 μs | 3.130 μs | 2.928 μs | 231.70 μs | 1.00 | 0.02 | 26.1230 | 429.6 KB | 1.00 |
VolumeFlowToString | .NET 8.0 | .NET 8.0 | 1000 | S | 233.04 μs | 3.050 μs | 2.704 μs | 232.35 μs | 1.00 | 0.02 | 26.3672 | 434.66 KB | 1.01 |
MassToString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | S | 669.36 μs | 5.894 μs | 5.514 μs | 667.54 μs | 1.00 | 0.01 | 106.4453 | 659.27 KB | 1.00 |
VolumeFlowToString | .NET Framework 4.8 | .NET Framework 4.8 | 1000 | S | 700.49 μs | 8.046 μs | 7.526 μs | 697.33 μs | 1.05 | 0.01 | 108.3984 | 667.51 KB | 1.01 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.. I fixed the method names, but didn't bother re-running the benchmark..
UnitsNet/CustomCode/Quantity.cs
Outdated
public static string[] Names { get => Default.Names; } | ||
public static IReadOnlyCollection<string> Names { get => Quantities.Names; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please note this breaking change: I think there simply is no way around it - we'd have to do it at some point..
I could have probably gotten away with an IReadOnlyList
but I think this is better: the backing dictionary serves a dual purpose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed my mind on this, fuck the SortedDictionary
I think I'm gonna go with the IReadOnlyList
variant (if not for the names, then at least for the QuantityInfo
collection):
Method | Job | Runtime | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|
ForLoopList | .NET 8.0 | .NET 8.0 | 53.52 μs | 0.279 μs | 0.261 μs | 53.51 μs | 1.00 | 0.01 | - | - | NA |
EnumerateList | .NET 8.0 | .NET 8.0 | 225.59 μs | 4.511 μs | 11.804 μs | 221.78 μs | 4.21 | 0.22 | 1.9531 | 40000 B | NA |
EnumerateSet | .NET 8.0 | .NET 8.0 | 128.22 μs | 0.310 μs | 0.275 μs | 128.21 μs | 2.40 | 0.01 | 1.7090 | 32000 B | NA |
EnumerateDictionary | .NET 8.0 | .NET 8.0 | 144.13 μs | 0.240 μs | 0.225 μs | 144.07 μs | 2.69 | 0.01 | 3.1738 | 56000 B | NA |
EnumerateSortedDictionary | .NET 8.0 | .NET 8.0 | 928.59 μs | 17.819 μs | 19.805 μs | 928.18 μs | 17.35 | 0.37 | 11.7188 | 208001 B | NA |
ForLoopList | .NET 9.0 | .NET 9.0 | 54.08 μs | 0.107 μs | 0.095 μs | 54.08 μs | 1.00 | 0.00 | - | - | NA |
EnumerateList | .NET 9.0 | .NET 9.0 | 191.29 μs | 1.693 μs | 1.584 μs | 190.84 μs | 3.54 | 0.03 | 2.1973 | 40000 B | NA |
EnumerateSet | .NET 9.0 | .NET 9.0 | 138.43 μs | 0.810 μs | 0.718 μs | 138.57 μs | 2.56 | 0.01 | 1.7090 | 32000 B | NA |
EnumerateDictionary | .NET 9.0 | .NET 9.0 | 169.38 μs | 1.550 μs | 1.450 μs | 168.91 μs | 3.13 | 0.03 | 3.1738 | 56000 B | NA |
EnumerateSortedDictionary | .NET 9.0 | .NET 9.0 | 808.44 μs | 15.826 μs | 27.719 μs | 811.42 μs | 14.95 | 0.51 | 11.7188 | 208001 B | NA |
ForLoopList | .NET Framework 4.8 | .NET Framework 4.8 | 172.25 μs | 0.732 μs | 0.685 μs | 172.41 μs | 1.00 | 0.01 | - | - | NA |
EnumerateList | .NET Framework 4.8 | .NET Framework 4.8 | 605.17 μs | 5.267 μs | 4.669 μs | 606.06 μs | 3.51 | 0.03 | 5.8594 | 40120 B | NA |
EnumerateSet | .NET Framework 4.8 | .NET Framework 4.8 | 623.37 μs | 10.318 μs | 9.147 μs | 622.94 μs | 3.62 | 0.05 | 5.8594 | 40120 B | NA |
EnumerateDictionary | .NET Framework 4.8 | .NET Framework 4.8 | 664.64 μs | 11.315 μs | 10.585 μs | 664.30 μs | 3.86 | 0.06 | 5.8594 | 40120 B | NA |
EnumerateSortedDictionary | .NET Framework 4.8 | .NET Framework 4.8 | 1,935.67 μs | 22.253 μs | 20.816 μs | 1,938.44 μs | 11.24 | 0.12 | 35.1563 | 240708 B | NA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ended up keeping the IReadOnlyCollection<string>
and just changing the IReadOnlyCollection<QuantityInfo>
into IReadOnlyList<QuantityInfo>
(fixed in 6dc5f09), and the Names
are now backed by a regular Dictionary, meaning they should come out sorted in whatever order they were provided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ended up keeping the
IReadOnlyCollection<string>
and just changing theIReadOnlyCollection<QuantityInfo>
intoIReadOnlyList<QuantityInfo>
(fixed in 6dc5f09), and theNames
are now backed by a regular Dictionary, meaning they should come out sorted in whatever order they were provided.
Actually this isn't true - the FrozenDictionary
is going to sort the names alphabetically, not in the order in which they are provided. This is mostly irrelevant for the now, as there is no way to provide anything to the UnitsNetSetup.Default
..
UnitsNet/CustomCode/Quantity.cs
Outdated
public static QuantityInfo[] Infos => Default.Infos; | ||
public static IReadOnlyCollection<QuantityInfo> Infos => Quantities.Infos; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the second breaking change: same deal- can't have users setting the values of the array.
I would also like to make Quantity.ByName
dictionary read-only:
/// <summary>
/// All QuantityInfo instances mapped by quantity name that are present in the <see cref="UnitsNetSetup.Default"/> configuration.
/// </summary>
public static IReadOnlyDictionary<string, QuantityInfo> ByName => Quantities.ByName;
The generated part of the Quantity
class should only contain a single collection of QuantityInfo
that we should pass to the QuantityInfoLookup
. Here's what I have in the other project:
public partial class Quantity
{
/// <summary>
/// Serves as a repository for predefined quantity conversion mappings, facilitating the automatic generation and retrieval of unit conversions in the UnitsNet library.
/// </summary>
internal static class Provider
{
/// <summary>
/// All QuantityInfo instances that are present in UnitsNet by default.
/// </summary>
internal static IReadOnlyCollection<QuantityInfo> DefaultQuantities => new QuantityInfo[]
{
AbsorbedDoseOfIonizingRadiation.Info,
// TODO Support custom units (via the QuantityParser), currently only hardcoded built-in quantities are supported. | ||
if (!typeof(IQuantity).IsAssignableFrom(quantityType)) | ||
throw new ArgumentException($"Type {quantityType} must be of type UnitsNet.IQuantity."); | ||
|
||
if (TryParse(formatProvider, quantityType, quantityString, out IQuantity? quantity)) | ||
return quantity; | ||
|
||
throw new UnitNotFoundException($"Quantity string '{quantityString}' could not be parsed to quantity '{quantityType}'."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my other project- the QuantityParser
can directly instantiate an IQuantity
(by calling the QuantityInfoLookup.From(..)
).
/// <summary> | ||
/// Get a list of quantities having the given base dimensions. | ||
/// </summary> | ||
/// <param name="quantityInfos">The type of quantity mapping information.</param> | ||
/// <param name="baseDimensions">The base dimensions to match.</param> | ||
public static IEnumerable<QuantityInfo> GetQuantitiesWithBaseDimensions(this IEnumerable<QuantityInfo> quantityInfos, | ||
BaseDimensions baseDimensions) | ||
{ | ||
if (baseDimensions is null) | ||
{ | ||
throw new ArgumentNullException(nameof(baseDimensions)); | ||
} | ||
|
||
return quantityInfos.Where(info => info.BaseDimensions.Equals(baseDimensions)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This extensions doesn't have to be public: it's currently only used from the Quantity
class.
/// Quantity value type, such as <see cref="Length"/> or <see cref="Mass"/>. | ||
/// Quantity value type, such as <see cref="Length" /> or <see cref="Mass" />. | ||
/// </summary> | ||
public Type ValueType { get; } | ||
public Type QuantityType { get; } | ||
|
||
/// <inheritdoc cref="QuantityType" /> | ||
[Obsolete("Replaced by the QuantityType property.")] | ||
[DebuggerBrowsable(DebuggerBrowsableState.Never)] | ||
public Type ValueType | ||
{ | ||
get => QuantityType; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope you don't mind- this has been bugging me for ages...
public static double ConvertByName(double fromValue, string quantityName, string fromUnit, string toUnit) | ||
public static double ConvertByName(double fromValue, string quantityName, string fromUnitName, string toUnitName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically this is another breaking change..
[Obsolete("Methods accepting a culture name are deprecated in favor of using an instance of the IFormatProvider.")] | ||
public static double ConvertByAbbreviation(double fromValue, string quantityName, string fromUnitAbbrev, string toUnitAbbrev, string? culture) | ||
{ | ||
if (!TryGetUnitType(quantityName, out Type? unitType)) | ||
throw new UnitNotFoundException($"The unit type for the given quantity was not found: {quantityName}"); | ||
|
||
var cultureInfo = CultureHelper.GetCultureOrInvariant(culture); | ||
|
||
var fromUnit = UnitsNetSetup.Default.UnitParser.Parse(fromUnitAbbrev, unitType, cultureInfo); // ex: ("m", LengthUnit) => LengthUnit.Meter | ||
var fromQuantity = Quantity.From(fromValue, fromUnit); | ||
return ConvertByAbbreviation(fromValue, quantityName, fromUnitAbbrev, toUnitAbbrev, CultureHelper.GetCultureOrInvariant(culture)); | ||
} | ||
|
||
var toUnit = UnitsNetSetup.Default.UnitParser.Parse(toUnitAbbrev, unitType, cultureInfo); // ex:("cm", LengthUnit) => LengthUnit.Centimeter | ||
return fromQuantity.As(toUnit); | ||
/// <summary> | ||
/// Convert between any two quantity units by their abbreviations, such as converting a "Length" of N "m" to "cm". | ||
/// This is particularly useful for creating things like a generated unit conversion UI, | ||
/// where you list some selectors: | ||
/// a) Quantity: Length, Mass, Force etc. | ||
/// b) From unit: Meter, Centimeter etc if Length is selected | ||
/// c) To unit: Meter, Centimeter etc if Length is selected | ||
/// </summary> | ||
/// <param name="fromValue"> | ||
/// Input value, which together with <paramref name="fromUnitAbbrev" /> represents the quantity to | ||
/// convert from. | ||
/// </param> | ||
/// <param name="quantityName">The invariant quantity name, such as "Length". Does not support localization.</param> | ||
/// <param name="fromUnitAbbrev">The abbreviation of the unit in the given culture, such as "m".</param> | ||
/// <param name="toUnitAbbrev">The abbreviation of the unit in the given culture, such as "m".</param> | ||
/// <param name="formatProvider"> | ||
/// The format provider to use for lookup. Defaults to <see cref="System.Globalization.CultureInfo.CurrentCulture" /> | ||
/// if null. | ||
/// </param> | ||
/// <example>double centimeters = ConvertByName(5, "Length", "m", "cm"); // 500</example> | ||
/// <returns>Output value as the result of converting to <paramref name="toUnitAbbrev" />.</returns> | ||
/// <exception cref="QuantityNotFoundException"> | ||
/// Thrown when no quantity information is found for the specified quantity name. | ||
/// </exception> | ||
/// <exception cref="UnitNotFoundException">No units match the abbreviation.</exception> | ||
/// <exception cref="AmbiguousUnitParseException">More than one unit matches the abbreviation.</exception> | ||
public static double ConvertByAbbreviation(double fromValue, string quantityName, string fromUnitAbbrev, string toUnitAbbrev, IFormatProvider? formatProvider) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added an IFormatProvider?
overload and deprecated the whole CultureHelper
class:
string -> CultureInfo conversions are not in the scope of UnitsNet
If you want to- we could also make this for v5
and have the string?
overload directly removed in v6
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I think I see what the deal is- the UnitParser
doesn't really care about the IFormat
part of the IFormatProvider
, just the CultureName
.. I wonder if there is a more standard way of dealing with things that depend solely on the language / region (and not that number-formatting stuff).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we ultimately depend on the ResourceManager
, and it takes a CultureInfo?
as it's second parameter, I think the right way (another breaking change) would be to make everything that doesn't involve formatting the number (i.e. everything in the UnitParser
, UnitAbbreviationsCache
, as well as this new overload that I just added) use a CultureInfo?
(with the rest of the code safe-casting the IFormatProvider?
)..
Oh, I just remembered that there are two more benchmarks that I forgot to post: Before:
After:
|
TryParseInvalidUnitBenchmarks.cs Before:
After:
Eh, yeah - I've made the number of iterations a constant 1000 but didn't bother to update the result (I used to think it would make sense to provide the number of iterations in the report). |
…r with IReadOnlyCollection<QuantityInfo> - UnitsNetSetup: replaced the ICollection<QuantityInfo> parameter with IReadOnlyCollection<QuantityInfo> - UnitAbbreviationsCache: introduced a constructor with a list of quantities, and improve the comments of the other constructors - added tests and benchmarks covering the UnitAbbreviations initializations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before (without the new constructor):
Method | Job | Runtime | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|
Default | .NET 8.0 | .NET 8.0 | 107,378.0 ns | 1,866.42 ns | 1,745.85 ns | 1.000 | 0.02 | 9.0332 | 2.1973 | 148.21 KB | 1.00 |
EmptyWithCustomMapping | .NET 8.0 | .NET 8.0 | 623.6 ns | 12.26 ns | 15.94 ns | 0.006 | 0.00 | 0.1793 | 0.0010 | 2.94 KB | 0.02 |
DefaultWithoutLookup | .NET 8.0 | .NET 8.0 | 4,326.9 ns | 75.43 ns | 66.87 ns | 0.040 | 0.00 | 0.4959 | - | 8.16 KB | 0.06 |
EmptyWithoutLookup | .NET 8.0 | .NET 8.0 | 3,225.0 ns | 61.52 ns | 57.55 ns | 0.030 | 0.00 | 0.3586 | - | 5.94 KB | 0.04 |
Default | .NET Framework 4.8 | .NET Framework 4.8 | 166,492.9 ns | 2,520.02 ns | 2,357.22 ns | 1.00 | 0.02 | 25.3906 | 5.6152 | 156.56 KB | 1.00 |
EmptyWithCustomMapping | .NET Framework 4.8 | .NET Framework 4.8 | 2,189.2 ns | 27.21 ns | 25.45 ns | 0.01 | 0.00 | 0.5646 | 0.0038 | 3.48 KB | 0.02 |
DefaultWithoutLookup | .NET Framework 4.8 | .NET Framework 4.8 | 12,468.0 ns | 134.59 ns | 125.90 ns | 0.07 | 0.00 | 1.9379 | 0.0153 | 11.97 KB | 0.08 |
EmptyWithoutLookup | .NET Framework 4.8 | .NET Framework 4.8 | 10,682.9 ns | 92.34 ns | 81.86 ns | 0.06 | 0.00 | 1.4343 | 0.0153 | 8.89 KB | 0.06 |
After:
Method | Job | Runtime | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|
Default | .NET 8.0 | .NET 8.0 | 48,822.3 ns | 478.55 ns | 424.22 ns | 1.000 | 0.01 | 8.4229 | 1.8311 | 138.32 KB | 1.00 |
EmptyWithCustomMapping | .NET 8.0 | .NET 8.0 | 466.2 ns | 9.33 ns | 16.10 ns | 0.010 | 0.00 | 0.1945 | 0.0019 | 3.18 KB | 0.02 |
WithSpecificQuantity | .NET 8.0 | .NET 8.0 | 3,787.3 ns | 27.75 ns | 25.96 ns | 0.078 | 0.00 | 0.5188 | - | 8.61 KB | 0.06 |
WithSpecificQuantityAndCustomMapping | .NET 8.0 | .NET 8.0 | 4,086.7 ns | 80.18 ns | 92.33 ns | 0.084 | 0.00 | 0.5493 | - | 8.98 KB | 0.06 |
DefaultWithoutLookup | .NET 8.0 | .NET 8.0 | 3,175.6 ns | 61.39 ns | 75.39 ns | 0.065 | 0.00 | 0.3586 | - | 5.94 KB | 0.04 |
EmptyWithoutLookup | .NET 8.0 | .NET 8.0 | 3,269.1 ns | 62.13 ns | 63.81 ns | 0.067 | 0.00 | 0.3586 | - | 5.94 KB | 0.04 |
WithSpecificQuantityWithoutLookup | .NET 8.0 | .NET 8.0 | 3,223.6 ns | 63.93 ns | 62.79 ns | 0.066 | 0.00 | 0.3586 | - | 5.96 KB | 0.04 |
Default | .NET Framework 4.8 | .NET Framework 4.8 | 73,787.6 ns | 1,266.97 ns | 1,185.13 ns | 1.00 | 0.02 | 22.9492 | 4.5166 | 141.48 KB | 1.00 |
EmptyWithCustomMapping | .NET Framework 4.8 | .NET Framework 4.8 | 1,146.8 ns | 11.71 ns | 10.38 ns | 0.02 | 0.00 | 0.5398 | 0.0038 | 3.32 KB | 0.02 |
WithSpecificQuantity | .NET Framework 4.8 | .NET Framework 4.8 | 11,476.0 ns | 118.92 ns | 111.24 ns | 0.16 | 0.00 | 1.8768 | 0.0305 | 11.57 KB | 0.08 |
WithSpecificQuantityAndCustomMapping | .NET Framework 4.8 | .NET Framework 4.8 | 11,915.2 ns | 136.68 ns | 127.85 ns | 0.16 | 0.00 | 1.9379 | 0.0305 | 11.95 KB | 0.08 |
DefaultWithoutLookup | .NET Framework 4.8 | .NET Framework 4.8 | 10,557.8 ns | 133.17 ns | 124.57 ns | 0.14 | 0.00 | 1.4343 | 0.0153 | 8.84 KB | 0.06 |
EmptyWithoutLookup | .NET Framework 4.8 | .NET Framework 4.8 | 10,369.5 ns | 52.83 ns | 41.24 ns | 0.14 | 0.00 | 1.4343 | 0.0153 | 8.84 KB | 0.06 |
WithSpecificQuantityWithoutLookup | .NET Framework 4.8 | .NET Framework 4.8 | 10,373.9 ns | 86.97 ns | 81.35 ns | 0.14 | 0.00 | 1.4343 | 0.0153 | 8.86 KB | 0.06 |
…sing backing fields) - added some benchmarks for the Enum/UnitKey - updated some typos for the TryParseUnitBenchmarks and introduced an explict Culture for the Parse/TryParse unit benchmarks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a before and after 6b4d05a
Before:
Method | Job | Runtime | Mean | Error | StdDev | Ratio |
---|---|---|---|---|---|---|
EqualsRecord | .NET 8.0 | .NET 8.0 | 186.6 ns | 0.60 ns | 0.53 ns | 1.00 |
OperatorEqualsRecord | .NET 8.0 | .NET 8.0 | 186.1 ns | 0.57 ns | 0.54 ns | 1.00 |
OperatorEqualsManual | .NET 8.0 | .NET 8.0 | 329.6 ns | 1.68 ns | 1.57 ns | 1.77 |
EqualsRecord | .NET Framework 4.8 | .NET Framework 4.8 | 5,670.3 ns | 11.10 ns | 9.84 ns | 1.00 |
OperatorEqualsRecord | .NET Framework 4.8 | .NET Framework 4.8 | 5,862.4 ns | 26.46 ns | 24.75 ns | 1.03 |
OperatorEqualsManual | .NET Framework 4.8 | .NET Framework 4.8 | 1,321.3 ns | 4.87 ns | 4.32 ns | 0.23 |
After:
Method | Job | Runtime | Mean | Error | StdDev | Ratio |
---|---|---|---|---|---|---|
EqualsRecord | .NET 8.0 | .NET 8.0 | 186.6 ns | 0.27 ns | 0.24 ns | 1.00 |
OperatorEqualsRecord | .NET 8.0 | .NET 8.0 | 186.6 ns | 0.24 ns | 0.20 ns | 1.00 |
OperatorEqualsManual | .NET 8.0 | .NET 8.0 | 328.6 ns | 1.11 ns | 1.04 ns | 1.76 |
EqualsRecord | .NET Framework 4.8 | .NET Framework 4.8 | 1,325.5 ns | 3.55 ns | 3.32 ns | 1.00 |
OperatorEqualsRecord | .NET Framework 4.8 | .NET Framework 4.8 | 1,328.1 ns | 3.81 ns | 3.38 ns | 1.00 |
OperatorEqualsManual | .NET Framework 4.8 | .NET Framework 4.8 | 1,135.7 ns | 1.84 ns | 1.63 ns | 0.86 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before 6b4d05a :
Method | Job | Runtime | Mean | Error | StdDev | Ratio |
---|---|---|---|---|---|---|
GetHashCodeRecord | .NET 8.0 | .NET 8.0 | 1.367 μs | 0.0025 μs | 0.0023 μs | 1.00 |
GetCustomHashCode | .NET 8.0 | .NET 8.0 | 2.369 μs | 0.0033 μs | 0.0028 μs | 1.73 |
GetCustomHashCodeUnchecked | .NET 8.0 | .NET 8.0 | 1.314 μs | 0.0027 μs | 0.0024 μs | 0.96 |
GetHashCodeRecord | .NET Framework 4.8 | .NET Framework 4.8 | 6.964 μs | 0.0096 μs | 0.0085 μs | 1.00 |
GetCustomHashCode | .NET Framework 4.8 | .NET Framework 4.8 | 1.512 μs | 0.0032 μs | 0.0030 μs | 0.22 |
GetCustomHashCodeUnchecked | .NET Framework 4.8 | .NET Framework 4.8 | 1.696 μs | 0.0029 μs | 0.0027 μs | 0.24 |
After 6b4d05a :
Method | Job | Runtime | Mean | Error | StdDev | Ratio |
---|---|---|---|---|---|---|
GetHashCodeRecord | .NET 8.0 | .NET 8.0 | 1.312 μs | 0.0019 μs | 0.0017 μs | 1.00 |
GetCustomHashCode | .NET 8.0 | .NET 8.0 | 2.371 μs | 0.0059 μs | 0.0052 μs | 1.81 |
GetCustomHashCodeUnchecked | .NET 8.0 | .NET 8.0 | 1.321 μs | 0.0044 μs | 0.0041 μs | 1.01 |
GetHashCodeRecord | .NET Framework 4.8 | .NET Framework 4.8 | 2.450 μs | 0.0039 μs | 0.0032 μs | 1.00 |
GetCustomHashCode | .NET Framework 4.8 | .NET Framework 4.8 | 1.513 μs | 0.0030 μs | 0.0026 μs | 0.62 |
GetCustomHashCodeUnchecked | .NET Framework 4.8 | .NET Framework 4.8 | 1.516 μs | 0.0014 μs | 0.0013 μs | 0.62 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before 6b4d05a :
Method | Job | Runtime | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|
ManualCast | .NET 8.0 | .NET 8.0 | 99.73 ns | 0.876 ns | 0.777 ns | 1.00 | 0.01 | - | - | NA |
ExplicitCast | .NET 8.0 | .NET 8.0 | 17,091.84 ns | 207.027 ns | 193.653 ns | 171.39 | 2.27 | 0.7019 | 12000 B | NA |
ExplicitCastBoxed | .NET 8.0 | .NET 8.0 | 14,396.40 ns | 151.136 ns | 141.373 ns | 144.36 | 1.75 | 1.4343 | 24000 B | NA |
ToUnit | .NET 8.0 | .NET 8.0 | 100.33 ns | 1.660 ns | 1.553 ns | 1.01 | 0.02 | - | - | NA |
ManualCast | .NET Framework 4.8 | .NET Framework 4.8 | 97.67 ns | 1.226 ns | 1.147 ns | 1.00 | 0.02 | - | - | NA |
ExplicitCast | .NET Framework 4.8 | .NET Framework 4.8 | 23,538.91 ns | 190.287 ns | 148.563 ns | 241.03 | 3.11 | 1.8921 | 12035 B | NA |
ExplicitCastBoxed | .NET Framework 4.8 | .NET Framework 4.8 | 25,713.98 ns | 227.592 ns | 212.890 ns | 263.30 | 3.66 | 3.8147 | 24071 B | NA |
ToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1,412.97 ns | 6.864 ns | 6.420 ns | 14.47 | 0.18 | - | - | NA |
After 6b4d05a :
Method | Job | Runtime | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|
ManualCast | .NET 8.0 | .NET 8.0 | 99.12 ns | 0.232 ns | 0.206 ns | 1.00 | 0.00 | - | - | NA |
ExplicitCast | .NET 8.0 | .NET 8.0 | 12,441.49 ns | 30.149 ns | 26.726 ns | 125.51 | 0.36 | 0.7172 | 12000 B | NA |
ExplicitCastBoxed | .NET 8.0 | .NET 8.0 | 14,356.90 ns | 128.752 ns | 120.435 ns | 144.84 | 1.21 | 1.4343 | 24000 B | NA |
ToUnit | .NET 8.0 | .NET 8.0 | 98.93 ns | 0.209 ns | 0.185 ns | 1.00 | 0.00 | - | - | NA |
ManualCast | .NET Framework 4.8 | .NET Framework 4.8 | 95.62 ns | 0.076 ns | 0.059 ns | 1.00 | 0.00 | - | - | NA |
ExplicitCast | .NET Framework 4.8 | .NET Framework 4.8 | 22,978.83 ns | 105.611 ns | 98.789 ns | 240.32 | 1.01 | 1.8921 | 12035 B | NA |
ExplicitCastBoxed | .NET Framework 4.8 | .NET Framework 4.8 | 24,999.50 ns | 156.120 ns | 146.035 ns | 261.46 | 1.49 | 3.8147 | 24071 B | NA |
ToUnit | .NET Framework 4.8 | .NET Framework 4.8 | 1,037.09 ns | 1.759 ns | 1.560 ns | 10.85 | 0.02 | - | - | NA |
…ionary and optimized the lazy initializer
…d the _quantitiesByName into a regular (lazy-loaded) dictionary - UnitsNetSetup and UnitAbbreviationsCache constructors changed from IReadOnlyCollection<QuantityInfo> into IEnumerable<QuantityInfo> - changed the Quantity.Infos from IReadOnlyCollection to IReadOnlyList
@angularsen I think this is ready, I don't have anything more to add for the time being. There is of course a |
Oh boy, I'll need some time to just read through this 😄 |
Enum
boxing optimizations:UnitKey
struct as a replacement for the conversions fromTUnit
toEnum
UnitAbbreviationCache
using theUnitKey
for the concurrent dictionaryConvert.ToInt32(..)
callsQuantityInfoLookup
collectionsQuantity
/UnitConverter
code (using theUnitParser
/QuantityInfoLookup
)Breaking changes:
Quantity.Names
fromstring[]
toIReadOnlyCollection<string>
Quantity.Infos
fromQuantityInfo[]
toIReadOnlyList<QuantityInfo>
UnitConverter.ConvertByAbbreviation
method that takes astring?
for theIFormatProvider?
as[Obsolete]
(created an overload)UnitsNetSetup
: replaced theICollection<QuantityInfo>
constructor parameter withIEnumerable<QuantityInfo>
QuantityInfo.ValueType
toQuantityInfo.QuantityType
(making the old property[Obsolete]
)UnitConverter.ConvertByName