From 3f4398233aa3c346c502d2210c70138b7e17abd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Mon, 6 Nov 2023 13:36:03 +0100 Subject: [PATCH] Simplify usage of exponents on measures. --- .../Quantities.Benchmark/CreateQuantities.cs | 35 +++++++++--------- source/Quantities/Core/IFactory.cs | 12 +++---- .../Measures/{Dimensions.cs => Exponents.cs} | 6 ++-- source/Quantities/Measures/Measures.cs | 36 +++++++++---------- 4 files changed, 42 insertions(+), 47 deletions(-) rename source/Quantities/Measures/{Dimensions.cs => Exponents.cs} (63%) diff --git a/source/Quantities.Benchmark/CreateQuantities.cs b/source/Quantities.Benchmark/CreateQuantities.cs index eec9b12a..05895496 100644 --- a/source/Quantities.Benchmark/CreateQuantities.cs +++ b/source/Quantities.Benchmark/CreateQuantities.cs @@ -5,30 +5,29 @@ using Quantities.Units.Si; using Quantities.Units.Si.Derived; using Quantities.Units.Si.Metric; -using Quantities.Dimensions; namespace Quantities.Benchmark; -internal readonly struct DummyQuant +internal readonly struct DummyQuantity { private readonly Double value; public Double Value => this.value; - public DummyQuant(in Double value) => this.value = value; + public DummyQuantity(in Double value) => this.value = value; } public sealed class DummyObject : ICastOperators { - private readonly DummyQuant value; - private DummyObject(in DummyQuant value) => this.value = value; - public static DummyObject Of(in Double value) => new(new DummyQuant(in value)); + private readonly DummyQuantity value; + private DummyObject(in DummyQuantity value) => this.value = value; + public static DummyObject Of(in Double value) => new(new DummyQuantity(in value)); public static implicit operator Double(DummyObject obj) => obj.value.Value; } public readonly struct DummyStruct : ICastOperators { - private readonly DummyQuant value; - private DummyStruct(in DummyQuant value) => this.value = value; - public static DummyStruct Of(in Double value) => new(new DummyQuant(in value)); + private readonly DummyQuantity value; + private DummyStruct(in DummyQuantity value) => this.value = value; + public static DummyStruct Of(in Double value) => new(new DummyQuantity(in value)); public static implicit operator Double(DummyStruct obj) => obj.value.Value; } @@ -82,13 +81,13 @@ .NET SDK 7.0.113 | Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | |------------------------------- |----------:|----------:|----------:|------:|--------:|-------:|----------:|------------:| -| CreateObject | 6.340 ns | 0.0561 ns | 0.0497 ns | 1.00 | 0.00 | 0.0057 | 24 B | 1.00 | -| CreateStruct | 1.643 ns | 0.0202 ns | 0.0189 ns | 0.26 | 0.00 | - | - | 0.00 | -| CreateScalarQuantity | 5.738 ns | 0.0110 ns | 0.0098 ns | 0.90 | 0.01 | - | - | 0.00 | -| CreateScalarQuantityWithoutOpt | 4.704 ns | 0.0108 ns | 0.0090 ns | 0.74 | 0.01 | - | - | 0.00 | -| CreateQuotientQuantity | 15.821 ns | 0.0588 ns | 0.0491 ns | 2.50 | 0.02 | - | - | 0.00 | -| CreateProductQuantity | 16.747 ns | 0.3553 ns | 0.3802 ns | 2.64 | 0.06 | - | - | 0.00 | -| CreateCachedProductQuantity | 5.459 ns | 0.1217 ns | 0.1138 ns | 0.86 | 0.02 | - | - | 0.00 | -| CreateScalarPowerQuantity | 14.589 ns | 0.0475 ns | 0.0397 ns | 2.30 | 0.02 | - | - | 0.00 | -| CreateSquarePowerQuantity | 5.511 ns | 0.0224 ns | 0.0198 ns | 0.87 | 0.01 | - | - | 0.00 | +| CreateObject | 6.458 ns | 0.0909 ns | 0.0850 ns | 1.00 | 0.00 | 0.0057 | 24 B | 1.00 | +| CreateStruct | 1.635 ns | 0.0607 ns | 0.0596 ns | 0.25 | 0.01 | - | - | 0.00 | +| CreateScalarQuantity | 5.428 ns | 0.0489 ns | 0.0457 ns | 0.84 | 0.01 | - | - | 0.00 | +| CreateScalarQuantityWithoutOpt | 4.546 ns | 0.0143 ns | 0.0119 ns | 0.71 | 0.01 | - | - | 0.00 | +| CreateQuotientQuantity | 15.384 ns | 0.0957 ns | 0.0849 ns | 2.39 | 0.03 | - | - | 0.00 | +| CreateProductQuantity | 15.997 ns | 0.3390 ns | 0.3628 ns | 2.47 | 0.04 | - | - | 0.00 | +| CreateCachedProductQuantity | 5.515 ns | 0.0123 ns | 0.0115 ns | 0.85 | 0.01 | - | - | 0.00 | +| CreateScalarPowerQuantity | 13.346 ns | 0.0560 ns | 0.0467 ns | 2.07 | 0.02 | - | - | 0.00 | +| CreateSquarePowerQuantity | 5.402 ns | 0.0391 ns | 0.0347 ns | 0.84 | 0.01 | - | - | 0.00 | */ diff --git a/source/Quantities/Core/IFactory.cs b/source/Quantities/Core/IFactory.cs index 9c50b307..ed5e8903 100644 --- a/source/Quantities/Core/IFactory.cs +++ b/source/Quantities/Core/IFactory.cs @@ -11,7 +11,7 @@ public interface IFactory } public interface IScalar - where TQuantity : struct, IScalar, TDimension + where TQuantity : IScalar, TDimension where TDimension : IDimension { public TQuantity To(in Scalar other) where TUnit : TDimension, IUnit; @@ -19,7 +19,7 @@ public interface IScalar } public interface IQuotient : IScalar - where TQuantity : struct, IQuotient, TDimension + where TQuantity : IQuotient, TDimension where TDimension : IQuotient where TNominatorDimension : IDimension where TDenominatorDimension : IDimension @@ -33,7 +33,7 @@ public static abstract TQuantity Of(in Double value, i } public interface IProduct : IScalar - where TQuantity : struct, IProduct, TDimension + where TQuantity : IProduct, TDimension where TDimension : IProduct where TLeftDimension : IDimension where TRightDimension : IDimension @@ -47,7 +47,7 @@ public static abstract TQuantity Of(in Double value, in Product : IAlias - where TQuantity : struct, ISquare, TDimension + where TQuantity : ISquare, TDimension where TDimension : ISquare where TLinear : IDimension, ILinear { @@ -56,7 +56,7 @@ public interface ISquare : IAlias : IAlias - where TQuantity : struct, ICubic, TDimension + where TQuantity : ICubic, TDimension where TDimension : ICubic where TLinear : IDimension, ILinear { @@ -65,7 +65,7 @@ public interface ICubic : IAlias - where TQuantity : struct, IAlias, TDimension + where TQuantity : IAlias, TDimension where TDimension : IDimension where TLinear : IDimension, ILinear { diff --git a/source/Quantities/Measures/Dimensions.cs b/source/Quantities/Measures/Exponents.cs similarity index 63% rename from source/Quantities/Measures/Dimensions.cs rename to source/Quantities/Measures/Exponents.cs index 3452db78..7c766c4d 100644 --- a/source/Quantities/Measures/Dimensions.cs +++ b/source/Quantities/Measures/Exponents.cs @@ -3,16 +3,14 @@ internal interface IExponent { public static abstract Int32 E { get; } - public static abstract String Representation { get; } } + internal readonly struct Square : IExponent { public static Int32 E => 2; - public static String Representation => "²"; - } + internal readonly struct Cubic : IExponent { public static Int32 E => 3; - public static String Representation => "³"; } diff --git a/source/Quantities/Measures/Measures.cs b/source/Quantities/Measures/Measures.cs index 8b8e9f13..bc5c8faa 100644 --- a/source/Quantities/Measures/Measures.cs +++ b/source/Quantities/Measures/Measures.cs @@ -4,8 +4,6 @@ using Quantities.Prefixes; using Quantities.Units; -using static Quantities.Measures.Convenience; - namespace Quantities.Measures; file interface IOps @@ -165,7 +163,7 @@ public static void Write(IWriter writer) private static readonly String dimension = typeof(TDim).Name.ToLowerInvariant(); static Dimension IMeasure.D { get; } = TLinear.D.Pow(TDim.E); public static Polynomial Poly { get; } = TLinear.Poly.Pow(TDim.E); - public static String Representation { get; } = $"{TLinear.Representation}{TDim.Representation}"; + public static String Representation { get; } = $"{TLinear.Representation}{Tools.ExpToString(TDim.E)}"; public static Result Multiply() where TOtherMeasure : IMeasure => HigherOrderOps, TLinear, TOtherMeasure>.Product; public static Result Divide() where TOtherMeasure : IMeasure => HigherOrderOps, TLinear, TOtherMeasure>.Quotient; public static void Write(IWriter writer) @@ -260,7 +258,7 @@ public static Result Multiply() where TArgument : IMeasure return new(polyProduct, Measure.Of()); } Measure? measure; - if (product is Scalar scalar && (measure = Pow(scalar.E)) != null) { + if (product is Scalar scalar && (measure = scalar.As()) != null) { return new(polyProduct / TLeft.Poly, measure); } return new(Polynomial.One, Measure.Of, TArgument>>()); @@ -273,7 +271,7 @@ public static Result Divide() where TArgument : IMeasure return new(polyQuotient, Measure.Of()); } Measure? measure; - if (quotient is Scalar scalar && (measure = Pow(scalar.E)) != null) { + if (quotient is Scalar scalar && (measure = scalar.As()) != null) { return new(polyQuotient / TLeft.Poly, measure); } return new(Polynomial.One, Measure.Of, TArgument>>()); @@ -293,7 +291,7 @@ public static Result Divide() where TArgument : IMeasure return new(polyQuotient, Measure.Of()); } Measure? measure; - if (quotient is Scalar scalar && (measure = Pow(scalar.E)) != null) { + if (quotient is Scalar scalar && (measure = scalar.As()) != null) { return new(polyQuotient / TNominator.Poly, measure); } return new(Polynomial.One, Measure.Of>>()); @@ -306,7 +304,7 @@ public static Result Divide() where TArgument : IMeasure public static Result Multiply() where TArgument : IMeasure { Dimension target = THigher.D * TArgument.D; - Measure? measure = Pow(target.E); + Measure? measure = target.As(); if (measure is null) { return new(Polynomial.One, Measure.Of>()); } @@ -316,7 +314,7 @@ public static Result Multiply() where TArgument : IMeasure public static Result Divide() where TArgument : IMeasure { Dimension target = THigher.D / TArgument.D; - Measure? measure = Pow(target.E); + Measure? measure = target.As(); if (measure is null) { return new(Polynomial.One, Measure.Of>()); } @@ -327,15 +325,15 @@ public static Result Divide() where TArgument : IMeasure file static class Convenience { - public static Measure? Pow(Int32 exp) - where TLinear : IMeasure => exp switch { - 3 => Measure.Of>(), - 2 => Measure.Of>(), - 1 => Measure.Of(), - 0 => Measure.Of(), - -1 => Measure.Of>(), - -2 => Measure.Of>>(), - -3 => Measure.Of>>(), - _ => null - }; + public static Measure? As(this Dimension d) + where TLinear : IMeasure => d.E switch { + 3 => Measure.Of>(), + 2 => Measure.Of>(), + 1 => Measure.Of(), + 0 => Measure.Of(), + -1 => Measure.Of>(), + -2 => Measure.Of>>(), + -3 => Measure.Of>>(), + _ => null + }; }