Skip to content

✨Set IsAotCompatible for net7.0 or later - #1543

Merged
angularsen merged 11 commits into
angularsen:masterfrom
OleRoss:annotate-is-native-aot-compatible
Jul 26, 2025
Merged

✨Set IsAotCompatible for net7.0 or later#1543
angularsen merged 11 commits into
angularsen:masterfrom
OleRoss:annotate-is-native-aot-compatible

Conversation

@OleRoss

@OleRossOleRoss commented Apr 13, 2025

Copy link
Copy Markdown
Contributor

Fixes IL warnings when building with AOT.

  • Add EnumHelper.GetValues<> to simplify enumerating enum values for netstandard and net7+, AOT compatible
  • Replace reflection in UnitConverter.RegisterDefaultConversions() with generated code in Quantity.DefaultProvider.RegisterUnitConversions()
  • Add attributes to warn about incompatibilities to Native AOT compilation for UnitsNet.Serialization.JsonNet, requires more changes

I tried to make minimal changes only, but possibly breaking changes are

  • the addition of a struct constraint to generic enum-constrained methods

Comment threadUnitsNet/CustomCode/UnitAbbreviationsCache.cs Outdated
- Add IsAotCompatible to UnitsNet
- Added EnumHelpers which provides a way to get enum values independent of target platform
- Replaced generation of `GetQuantityTypes` with `RegisterDefaultConversions` to avoid reflection
- Add IsAotCompatible to UnitsNet.NumberExtensions
- Add IsAotCompatible to UnitsNet.JsonNet
@OleRoss
OleRossforce-pushed the annotate-is-native-aot-compatible branch from fdb3f93 to ee4acd1CompareApril 25, 2025 17:14
@OleRoss

Copy link
Copy Markdown
ContributorAuthor

@angularsen I rebased on the current master - it was much easier due to the latest commits

And, just for fun, I added a startup performance comparison :)

Default startup performance (PerfTest_Startup):

| Name | Mean | StdDev | StdErr | Min | Max | P95 | P90 | Outliers |
| --------- | --------------- | ------------- | ------------ | --------------- | --------------- | --------------- | --------------- | -------- |
| Default | 2463,4326ms | 386,9283ms | 88,7674ms | 1930,7473ms | 3242,5405ms | 3182,9327ms | 3017,8285ms | 1 |

NativeAot compilation startup performance (PerfTest_Startup_Aot):

| Name | Mean | StdDev | StdErr | Min | Max | P95 | P90 | Outliers |
| ------- | --------- | -------- | --------- | ---------- | ---------- | ---------- | --- | -------- |
| Default | 186,438ms | 47,942ms | 10,9986ms | 280,4149ms | 279,2135ms | 275,9632ms | 1 | |

@lipchev

Copy link
Copy Markdown
Collaborator

@angularsen I rebased on the current master - it was much easier due to the latest commits

And, just for fun, I added a startup performance comparison :)

Default startup performance (PerfTest_Startup):

| Name | Mean | StdDev | StdErr | Min | Max | P95 | P90 | Outliers |
| --------- | --------------- | ------------- | ------------ | --------------- | --------------- | --------------- | --------------- | -------- |
| Default | 2463,4326ms | 386,9283ms | 88,7674ms | 1930,7473ms | 3242,5405ms | 3182,9327ms | 3017,8285ms | 1 |

NativeAot compilation startup performance (PerfTest_Startup_Aot):

| Name | Mean | StdDev | StdErr | Min | Max | P95 | P90 | Outliers |
| ------- | --------- | -------- | --------- | ---------- | ---------- | ---------- | --- | -------- |
| Default | 186,438ms | 47,942ms | 10,9986ms | 280,4149ms | 279,2135ms | 275,9632ms | 1 | |

@OleRoss I haven't been able to do my own aot-enabled publish (haven't installed the c++ stuff yet), but am very curious to see how the 🐲 version performs: if you got the time, could you please run it against this PR: #1544

@OleRoss

OleRoss commented Apr 26, 2025

Copy link
Copy Markdown
ContributorAuthor

@lipchev, sure, I played around with it, but had difficulties getting comparable results ...

I ended up creating a benchmark class which starts a process and waits for completion:

Run 1: IterationCount=20 LaunchCount=8 WarmupCount=5
| Method | Mean | Error | StdDev |
|------------------------------- |---------:|--------:|---------:|
| MeasureStartupQuantityValue | 869.8 ms | 6.28 ms | 23.37 ms |
| MeasureStartupQuantityValueAot | 204.2 ms | 3.39 ms | 12.59 ms |
| MeasureStartupMaster | 491.9 ms | 3.51 ms | 12.75 ms |
| MeasureStartupMasterAot | 171.7 ms | 1.48 ms | 5.49 ms |
Run 2: IterationCount=20 LaunchCount=8 WarmupCount=5
| Method | Mean | Error | StdDev | Median |
|------------------------------- |---------:|--------:|---------:|---------:|
| MeasureStartupMaster | 535.9 ms | 4.45 ms | 16.33 ms | 534.7 ms |
| MeasureStartupMasterAot | 181.8 ms | 9.68 ms | 36.27 ms | 173.1 ms |
| MeasureStartupQuantityValue | 798.5 ms | 7.67 ms | 28.29 ms | 792.3 ms |
| MeasureStartupQuantityValueAot | 200.9 ms | 1.78 ms | 6.60 ms | 199.7 ms |

Between Run 1 and Run 2, I changed the order of the tests; Somehow, the tests seem to be affected by this, but I think the trend is clear.

Apart from that, those are the results using timeitsharp (very inconsistent, just for completeness):

fractional-quantity-value:
| Name | Mean | StdDev | StdErr | Min | Max | P95 | P90 | Outliers |
| ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ---------- | -------- |
| Default | 1737,353ms | 321,2004ms | 73,6884ms | 1378,0007ms | 2417,7457ms | 2345,5968ms | 2174,4889m | 1 |
fractional-quantity-value AOT:
| Name | Mean | StdDev | StdErr | Min | Max | P95 | P90 | Outliers |
| ------- | ---------- | --------- | -------- | ---------- | --------- | ---------- | --- | -------- |
| Default | 106,8239ms | 11,6117ms | 2,7369ms | 142,3908ms | 136,828ms | 118,7921ms | 2 | |
master:
| Name | Mean | StdDev | StdErr | Min | Max | P95 | P90 | Outliers |
| ----------- | ----------- | ----------- | ----------- | ---------- | ----------- | ----------- | ----------- | -------- |
| Default | 955,7565ms | 200,4313ms | 45,9821ms | 739,7095ms | 1324,9328ms | 1324,5596ms | 1312,1677ms | 1 |
master AOT:
| Name | Mean | StdDev | StdErr | Min | Max | P95 | P90 | Outliers |
| ------- | ---------- | --------- | -------- | ---------- | -------- | ---------- | --- | -------- |
| Default | 108,8349ms | 10,5986ms | 2,3699ms | 127,2372ms | 125,85ms | 123,0387ms | 0 | |

@github-actions

Copy link
Copy Markdown
Contributor

This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions

Copy link
Copy Markdown
Contributor

This PR was automatically closed due to inactivity.

…aot-compatible
# Conflicts:
#	CodeGen/Generators/UnitsNetGen/QuantityGenerator.cs
#	CodeGen/Generators/UnitsNetGen/StaticQuantityGenerator.cs
#	UnitsNet/GeneratedCode/Quantities/AbsorbedDoseOfIonizingRadiation.g.cs
#	UnitsNet/GeneratedCode/Quantities/Acceleration.g.cs
#	UnitsNet/GeneratedCode/Quantities/AmountOfSubstance.g.cs
#	UnitsNet/GeneratedCode/Quantities/AmplitudeRatio.g.cs
#	UnitsNet/GeneratedCode/Quantities/Angle.g.cs
#	UnitsNet/GeneratedCode/Quantities/Area.g.cs
#	UnitsNet/GeneratedCode/Quantities/AreaDensity.g.cs
#	UnitsNet/GeneratedCode/Quantities/AreaMomentOfInertia.g.cs
#	UnitsNet/GeneratedCode/Quantities/BitRate.g.cs
#	UnitsNet/GeneratedCode/Quantities/BrakeSpecificFuelConsumption.g.cs
#	UnitsNet/GeneratedCode/Quantities/CoefficientOfThermalExpansion.g.cs
#	UnitsNet/GeneratedCode/Quantities/Compressibility.g.cs
#	UnitsNet/GeneratedCode/Quantities/Density.g.cs
#	UnitsNet/GeneratedCode/Quantities/DoseAreaProduct.g.cs
#	UnitsNet/GeneratedCode/Quantities/Duration.g.cs
#	UnitsNet/GeneratedCode/Quantities/DynamicViscosity.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricAdmittance.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricApparentEnergy.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricApparentPower.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricCapacitance.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricCharge.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricChargeDensity.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricConductance.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricConductivity.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricCurrent.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricCurrentDensity.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricCurrentGradient.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricField.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricImpedance.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricInductance.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricPotential.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricPotentialChangeRate.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricReactance.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricReactiveEnergy.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricReactivePower.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricResistance.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricResistivity.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricSurfaceChargeDensity.g.cs
#	UnitsNet/GeneratedCode/Quantities/ElectricSusceptance.g.cs
#	UnitsNet/GeneratedCode/Quantities/Energy.g.cs
#	UnitsNet/GeneratedCode/Quantities/EnergyDensity.g.cs
#	UnitsNet/GeneratedCode/Quantities/Entropy.g.cs
#	UnitsNet/GeneratedCode/Quantities/FluidResistance.g.cs
#	UnitsNet/GeneratedCode/Quantities/Force.g.cs
#	UnitsNet/GeneratedCode/Quantities/ForceChangeRate.g.cs
#	UnitsNet/GeneratedCode/Quantities/ForcePerLength.g.cs
#	UnitsNet/GeneratedCode/Quantities/Frequency.g.cs
#	UnitsNet/GeneratedCode/Quantities/FuelEfficiency.g.cs
#	UnitsNet/GeneratedCode/Quantities/HeatFlux.g.cs
#	UnitsNet/GeneratedCode/Quantities/HeatTransferCoefficient.g.cs
#	UnitsNet/GeneratedCode/Quantities/Illuminance.g.cs
#	UnitsNet/GeneratedCode/Quantities/Impulse.g.cs
#	UnitsNet/GeneratedCode/Quantities/Information.g.cs
#	UnitsNet/GeneratedCode/Quantities/Irradiance.g.cs
#	UnitsNet/GeneratedCode/Quantities/Irradiation.g.cs
#	UnitsNet/GeneratedCode/Quantities/Jerk.g.cs
#	UnitsNet/GeneratedCode/Quantities/KinematicViscosity.g.cs
#	UnitsNet/GeneratedCode/Quantities/LeakRate.g.cs
#	UnitsNet/GeneratedCode/Quantities/Length.g.cs
#	UnitsNet/GeneratedCode/Quantities/Level.g.cs
#	UnitsNet/GeneratedCode/Quantities/LinearDensity.g.cs
#	UnitsNet/GeneratedCode/Quantities/LinearPowerDensity.g.cs
#	UnitsNet/GeneratedCode/Quantities/Luminance.g.cs
#	UnitsNet/GeneratedCode/Quantities/Luminosity.g.cs
#	UnitsNet/GeneratedCode/Quantities/LuminousFlux.g.cs
#	UnitsNet/GeneratedCode/Quantities/LuminousIntensity.g.cs
#	UnitsNet/GeneratedCode/Quantities/MagneticField.g.cs
#	UnitsNet/GeneratedCode/Quantities/MagneticFlux.g.cs
#	UnitsNet/GeneratedCode/Quantities/Magnetization.g.cs
#	UnitsNet/GeneratedCode/Quantities/Mass.g.cs
#	UnitsNet/GeneratedCode/Quantities/MassConcentration.g.cs
#	UnitsNet/GeneratedCode/Quantities/MassFlow.g.cs
#	UnitsNet/GeneratedCode/Quantities/MassFlux.g.cs
#	UnitsNet/GeneratedCode/Quantities/MassFraction.g.cs
#	UnitsNet/GeneratedCode/Quantities/MassMomentOfInertia.g.cs
#	UnitsNet/GeneratedCode/Quantities/Molality.g.cs
#	UnitsNet/GeneratedCode/Quantities/MolarEnergy.g.cs
#	UnitsNet/GeneratedCode/Quantities/MolarEntropy.g.cs
#	UnitsNet/GeneratedCode/Quantities/MolarFlow.g.cs
#	UnitsNet/GeneratedCode/Quantities/MolarMass.g.cs
#	UnitsNet/GeneratedCode/Quantities/Molarity.g.cs
#	UnitsNet/GeneratedCode/Quantities/Permeability.g.cs
#	UnitsNet/GeneratedCode/Quantities/Permittivity.g.cs
#	UnitsNet/GeneratedCode/Quantities/PorousMediumPermeability.g.cs
#	UnitsNet/GeneratedCode/Quantities/Power.g.cs
#	UnitsNet/GeneratedCode/Quantities/PowerDensity.g.cs
#	UnitsNet/GeneratedCode/Quantities/PowerRatio.g.cs
#	UnitsNet/GeneratedCode/Quantities/Pressure.g.cs
#	UnitsNet/GeneratedCode/Quantities/PressureChangeRate.g.cs
#	UnitsNet/GeneratedCode/Quantities/RadiationEquivalentDose.g.cs
#	UnitsNet/GeneratedCode/Quantities/RadiationEquivalentDoseRate.g.cs
#	UnitsNet/GeneratedCode/Quantities/RadiationExposure.g.cs
#	UnitsNet/GeneratedCode/Quantities/Radioactivity.g.cs
#	UnitsNet/GeneratedCode/Quantities/Ratio.g.cs
#	UnitsNet/GeneratedCode/Quantities/RatioChangeRate.g.cs
#	UnitsNet/GeneratedCode/Quantities/ReciprocalArea.g.cs
#	UnitsNet/GeneratedCode/Quantities/ReciprocalLength.g.cs
#	UnitsNet/GeneratedCode/Quantities/RelativeHumidity.g.cs
#	UnitsNet/GeneratedCode/Quantities/RotationalAcceleration.g.cs
#	UnitsNet/GeneratedCode/Quantities/RotationalSpeed.g.cs
#	UnitsNet/GeneratedCode/Quantities/RotationalStiffness.g.cs
#	UnitsNet/GeneratedCode/Quantities/RotationalStiffnessPerLength.g.cs
#	UnitsNet/GeneratedCode/Quantities/Scalar.g.cs
#	UnitsNet/GeneratedCode/Quantities/SolidAngle.g.cs
#	UnitsNet/GeneratedCode/Quantities/SpecificEnergy.g.cs
#	UnitsNet/GeneratedCode/Quantities/SpecificEntropy.g.cs
#	UnitsNet/GeneratedCode/Quantities/SpecificFuelConsumption.g.cs
#	UnitsNet/GeneratedCode/Quantities/SpecificVolume.g.cs
#	UnitsNet/GeneratedCode/Quantities/SpecificWeight.g.cs
#	UnitsNet/GeneratedCode/Quantities/Speed.g.cs
#	UnitsNet/GeneratedCode/Quantities/StandardVolumeFlow.g.cs
#	UnitsNet/GeneratedCode/Quantities/Temperature.g.cs
#	UnitsNet/GeneratedCode/Quantities/TemperatureChangeRate.g.cs
#	UnitsNet/GeneratedCode/Quantities/TemperatureDelta.g.cs
#	UnitsNet/GeneratedCode/Quantities/TemperatureGradient.g.cs
#	UnitsNet/GeneratedCode/Quantities/ThermalConductivity.g.cs
#	UnitsNet/GeneratedCode/Quantities/ThermalInsulance.g.cs
#	UnitsNet/GeneratedCode/Quantities/Torque.g.cs
#	UnitsNet/GeneratedCode/Quantities/Turbidity.g.cs
#	UnitsNet/GeneratedCode/Quantities/VitaminA.g.cs
#	UnitsNet/GeneratedCode/Quantities/Volume.g.cs
#	UnitsNet/GeneratedCode/Quantities/VolumeConcentration.g.cs
#	UnitsNet/GeneratedCode/Quantities/VolumeFlow.g.cs
#	UnitsNet/GeneratedCode/Quantities/VolumeFlowPerArea.g.cs
#	UnitsNet/GeneratedCode/Quantities/VolumePerLength.g.cs
#	UnitsNet/GeneratedCode/Quantities/VolumetricHeatCapacity.g.cs
#	UnitsNet/GeneratedCode/Quantities/WarpingMomentOfInertia.g.cs
#	UnitsNet/GeneratedCode/Quantity.g.cs
#	UnitsNet/UnitConverter.cs
@angularsen

Copy link
Copy Markdown
Owner

Apologies, I've been away for some time. What is the state of this

@angularsenangularsen reopened this Jul 26, 2025
@angularsenangularsen changed the title Annotate is native aot compatibleSet IsAotCompatible for net7.0 or laterJul 26, 2025
@angularsenangularsen changed the title Set IsAotCompatible for net7.0 or later✨Set IsAotCompatible for net7.0 or laterJul 26, 2025
@angularsen
angularsen enabled auto-merge (squash) July 26, 2025 13:07
@angularsen

Copy link
Copy Markdown
Owner

Merged with latest master, separated out some diffs to make the PR more succinct. LGTM.

@angularsen
angularsen merged commit 6abb5f4 into angularsen:masterJul 26, 2025
1 check passed
@OleRoss

Copy link
Copy Markdown
ContributorAuthor

Thanks for taking the time and merging @angularsen

@OleRoss
OleRoss deleted the annotate-is-native-aot-compatible branch July 26, 2025 13:33
@angularsen

Copy link
Copy Markdown
Owner

Better late than never, I've heard 🙈

@angularsen

Copy link
Copy Markdown
Owner

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@OleRoss@lipchev@angularsen