diff --git a/.github/workflows/project-build.yml b/.github/workflows/project-build.yml
index a70d8cb..959aa4c 100644
--- a/.github/workflows/project-build.yml
+++ b/.github/workflows/project-build.yml
@@ -17,9 +17,12 @@ jobs:
- name: Build
run: dotnet build -c Release --no-restore
- - name: Test
+ - name: Unit tests
run: dotnet test -c Release --no-restore --no-build -v=normal --collect:"XPlat Code Coverage"
+ - name: Performance tests
+ run: dotnet test -c Release --no-restore --no-build -v=normal --filter TestCategory="PerfTests"
+
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4.0.1
with:
@@ -39,3 +42,10 @@ jobs:
path: bin/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/Release/*.nupkg
retention-days: 1
+ - name: Upload performance tests artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: performance-tests
+ path: bin/NoStringEvaluating.Tests/Release/PerformanceTestsResults/PerformanceTests.txt
+ retention-days: 90
+
diff --git a/BenchResults/Benchmark.xlsx b/BenchResults/Benchmark.xlsx
deleted file mode 100644
index 7d3eada..0000000
Binary files a/BenchResults/Benchmark.xlsx and /dev/null differ
diff --git a/BenchResults/both.html b/BenchResults/both.html
deleted file mode 100644
index 4855b89..0000000
--- a/BenchResults/both.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-ConsoleApp.Benchmark.BenchNumbers-20230209-135445
-
-
-
-
-
-BenchmarkDotNet=v0.13.4, OS=Windows 10 (10.0.19044.2486/21H2/November2021Update)
-11th Gen Intel Core i7-1185G7 3.00GHz, 1 CPU, 8 logical and 4 physical cores
-.NET SDK=7.0.101
- [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2
- Job-MQTNJN : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2
-
-InvocationCount=3 IterationCount=10 RunStrategy=Monitoring
-UnrollFactor=1 WarmupCount=2
-
-
-
- Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
-
-Empty_NoString | 24.74 ms | 0.829 ms | 0.548 ms | - | - | - | 3.22 KB |
-
NumberOnly_NoString | 38.10 ms | 1.113 ms | 0.736 ms | - | - | - | 3.61 KB |
-
Formula1_NoString | 45.39 ms | 2.245 ms | 1.485 ms | - | - | - | 3.74 KB |
-
Formula2_NoString | 88.92 ms | 4.535 ms | 2.999 ms | - | - | - | 4.6 KB |
-
Formula3_NoString | 85.46 ms | 1.402 ms | 0.927 ms | - | - | - | 5.08 KB |
-
Formula4_NoString | 286.13 ms | 14.831 ms | 9.810 ms | - | - | - | 9.84 KB |
-
Formula5_NoString | 135.77 ms | 2.910 ms | 1.925 ms | - | - | - | 4.98 KB |
-
Formula6_NoString | 322.18 ms | 1.654 ms | 1.094 ms | - | - | - | 8.26 KB |
-
Formula7_NoString | 128.52 ms | 1.588 ms | 1.050 ms | - | - | - | 4.8 KB |
-
Formula8_NoString | 258.23 ms | 5.151 ms | 3.407 ms | - | - | - | 6.59 KB |
-
Formula9_NoString | 553.44 ms | 9.307 ms | 6.156 ms | - | - | - | 10.96 KB |
-
Formula10_NoString | 226.04 ms | 4.389 ms | 2.903 ms | - | - | - | 5.65 KB |
-
Empty_MxParser | 97.18 ms | 1.172 ms | 0.775 ms | 66000.0000 | - | - | 406250.95 KB |
-
NumberOnly_MxParser | 88.39 ms | 2.043 ms | 1.351 ms | 24000.0000 | - | - | 148515.88 KB |
-
Formula1_MxParser | 134.85 ms | 1.794 ms | 1.186 ms | 44333.3333 | - | - | 273523.88 KB |
-
Formula2_MxParser | 455.16 ms | 4.682 ms | 3.097 ms | 184666.6667 | 333.3333 | - | 1133048.41 KB |
-
Formula3_MxParser | 580.63 ms | 7.148 ms | 4.728 ms | 270333.3333 | 1000.0000 | - | 1656536.5 KB |
-
Formula4_MxParser | 2,519.84 ms | 55.817 ms | 36.920 ms | 1135000.0000 | 22666.6667 | - | 6954199.7 KB |
-
Formula5_MxParser | 350.81 ms | 11.546 ms | 7.637 ms | 99333.3333 | - | - | 609594.48 KB |
-
Formula6_MxParser | 1,331.11 ms | 22.133 ms | 14.640 ms | 539333.3333 | 4000.0000 | - | 3305395.58 KB |
-
Formula7_MxParser | 321.38 ms | 9.344 ms | 6.180 ms | 131333.3333 | - | - | 804816.88 KB |
-
Formula8_MxParser | 694.13 ms | 20.828 ms | 13.777 ms | 341666.6667 | 1333.3333 | - | 2094014.2 KB |
-
Formula9_MxParser | 8,540.56 ms | 67.741 ms | 44.807 ms | 1447666.6667 | 366000.0000 | 5666.6667 | 9360871.28 KB |
-
Formula10_MxParser | 684.27 ms | 22.928 ms | 15.165 ms | 247333.3333 | 666.6667 | - | 1515846.02 KB |
-
-
-
diff --git a/CodeAnalysis.ruleset b/CodeAnalysis.ruleset
index ced4c68..8f8d4e3 100644
--- a/CodeAnalysis.ruleset
+++ b/CodeAnalysis.ruleset
@@ -1,5 +1,11 @@
+
+
+
+
+
+
diff --git a/Directory.Build.props b/Directory.Build.props
index 29919a8..267fdbd 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,6 +1,6 @@
- net7.0
+ net8
enable
$(MSBuildThisFileDirectory)
diff --git a/Directory.Packages.props b/Directory.Packages.props
index aff5818..5cae333 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -1,19 +1,18 @@
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/Images/Both.png b/Images/Both.png
deleted file mode 100644
index 608322b..0000000
Binary files a/Images/Both.png and /dev/null differ
diff --git a/Images/Graph.png b/Images/Graph.png
deleted file mode 100644
index 13a86bc..0000000
Binary files a/Images/Graph.png and /dev/null differ
diff --git a/Images/Table.png b/Images/Table.png
deleted file mode 100644
index 9f48864..0000000
Binary files a/Images/Table.png and /dev/null differ
diff --git a/NoStringEvaluating.Tests/Helpers/FormulaModelFactory.cs b/NoStringEvaluating.Tests/Helpers/FormulaModelFactory.cs
deleted file mode 100644
index dcd5d0e..0000000
--- a/NoStringEvaluating.Tests/Helpers/FormulaModelFactory.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using NoStringEvaluating.Models.Values;
-using NoStringEvaluating.Tests.Models;
-
-namespace NoStringEvaluating.Tests.Helpers;
-
-internal static class FormulaModelFactory
-{
- public static FormulaModel CreateTestModelToCheck(string formula, bool expectedOkresult)
- {
- var model = new FormulaModel(formula, "NULL", double.NaN, expectedOkresult);
- return model;
- }
-
- public static FormulaModel CreateTestModel(string formula, EvaluatorValue result, params (string, EvaluatorValue)[] arguments)
- {
- return CreateTestModel(formula, "NULL", result, arguments);
- }
-
- public static FormulaModel CreateTestModel(string formula, string parsedFormula, EvaluatorValue result, params (string, EvaluatorValue)[] arguments)
- {
- var model = new FormulaModel(formula, parsedFormula, result);
- foreach (var argument in arguments)
- {
- model.Arguments[argument.Item1] = argument.Item2;
- }
-
- return model;
- }
-}
diff --git a/NoStringEvaluating.Tests/Models/FormulaModel.cs b/NoStringEvaluating.Tests/Models/FormulaModel.cs
deleted file mode 100644
index 2ee3425..0000000
--- a/NoStringEvaluating.Tests/Models/FormulaModel.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using NoStringEvaluating.Models.Values;
-
-namespace NoStringEvaluating.Tests.Models;
-
-public class FormulaModel
-{
- public string Formula { get; }
-
- public string ParsedFormula { get; }
-
- public EvaluatorValue Result { get; }
-
- public bool ExpectedOkResult { get; }
-
- public Dictionary Arguments { get; }
-
- public FormulaModel(string formula, string parsedFormula, EvaluatorValue result, bool expectedOkResult = true)
- {
- Formula = formula;
- ParsedFormula = parsedFormula;
- Result = result;
- ExpectedOkResult = expectedOkResult;
- Arguments = new Dictionary();
- }
-
- public override string ToString()
- {
- return Formula;
- }
-}
diff --git a/NoStringEvaluating.sln b/NoStringEvaluating.sln
index a043bd3..43235c9 100644
--- a/NoStringEvaluating.sln
+++ b/NoStringEvaluating.sln
@@ -3,13 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32611.2
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoStringEvaluating", "NoStringEvaluating\NoStringEvaluating.csproj", "{40AB411F-6002-4A69-A73F-17C5B7FC1508}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoStringEvaluating", "src\NoStringEvaluating\NoStringEvaluating.csproj", "{40AB411F-6002-4A69-A73F-17C5B7FC1508}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoStringEvaluating.Tests", "NoStringEvaluating.Tests\NoStringEvaluating.Tests.csproj", "{48E04BE8-5BA6-409A-964E-13206F95BC8D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoStringEvaluating.Tests", "src\NoStringEvaluating.Tests\NoStringEvaluating.Tests.csproj", "{48E04BE8-5BA6-409A-964E-13206F95BC8D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{EA941063-94B8-4F97-A507-B5A7FD6A0B79}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "ConsoleApp\ConsoleApp.csproj", "{6A870F87-7BD9-4DB3-ACA2-0F2EFF9FB1D3}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "src\ConsoleApp\ConsoleApp.csproj", "{6A870F87-7BD9-4DB3-ACA2-0F2EFF9FB1D3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{88F0773E-1AA1-4C00-A8D8-F09B76A70BE9}"
ProjectSection(SolutionItems) = preProject
@@ -17,9 +17,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoStringEvaluating.Extensions.Microsoft.DependencyInjection", "NoStringEvaluating.Extensions.Microsoft.DependencyInjection\NoStringEvaluating.Extensions.Microsoft.DependencyInjection.csproj", "{03E4E4C4-C186-4865-AC39-8E5E192D7F14}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoStringEvaluating.Extensions.Microsoft.DependencyInjection", "src\NoStringEvaluating.Extensions.Microsoft.DependencyInjection\NoStringEvaluating.Extensions.Microsoft.DependencyInjection.csproj", "{03E4E4C4-C186-4865-AC39-8E5E192D7F14}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests", "NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests\NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests.csproj", "{95AC9D45-49F2-41A2-88BC-E800F932C356}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests", "src\NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests\NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests.csproj", "{95AC9D45-49F2-41A2-88BC-E800F932C356}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Ci", "Ci", "{F2A9F436-5A49-486D-B4E1-B1B38924F61B}"
ProjectSection(SolutionItems) = preProject
diff --git a/NoStringEvaluating/Exceptions/NoStringFunctionException.cs b/NoStringEvaluating/Exceptions/NoStringFunctionException.cs
deleted file mode 100644
index 53afe07..0000000
--- a/NoStringEvaluating/Exceptions/NoStringFunctionException.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace NoStringEvaluating.Exceptions;
-
-///
-/// Raises when function exception
-///
-public class NoStringFunctionException : Exception
-{
- ///
- /// Raises when function exception
- ///
- public NoStringFunctionException(string funcName)
- : base($"Function \"{funcName}\" has already added")
- {
- }
-}
diff --git a/NoStringEvaluating/Exceptions/VariableNotFoundException.cs b/NoStringEvaluating/Exceptions/VariableNotFoundException.cs
deleted file mode 100644
index e3cbcd6..0000000
--- a/NoStringEvaluating/Exceptions/VariableNotFoundException.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace NoStringEvaluating.Exceptions;
-
-///
-/// Raises when can't find a variable
-///
-public class VariableNotFoundException : Exception
-{
- ///
- /// VariableName
- ///
- public string VariableName { get; set; }
-
- ///
- /// Raises when can't find a variable
- ///
- public VariableNotFoundException(string variableName, string message)
- : base(message)
- {
- VariableName = variableName;
- }
-}
diff --git a/NoStringEvaluating/Nodes/Base/BaseFormulaNode.cs b/NoStringEvaluating/Nodes/Base/BaseFormulaNode.cs
deleted file mode 100644
index 3d3597a..0000000
--- a/NoStringEvaluating/Nodes/Base/BaseFormulaNode.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-namespace NoStringEvaluating.Nodes.Base;
-
-///
-/// Formula node
-///
-public abstract class BaseFormulaNode
-{
- ///
- /// Type key
- ///
- public NodeTypeEnum TypeKey { get; }
-
- ///
- /// Formula node
- ///
- protected BaseFormulaNode(NodeTypeEnum typeKey)
- {
- TypeKey = typeKey;
- }
-}
diff --git a/NoStringEvaluating/Nodes/Common/FormulaNodes.cs b/NoStringEvaluating/Nodes/Common/FormulaNodes.cs
deleted file mode 100644
index da71839..0000000
--- a/NoStringEvaluating/Nodes/Common/FormulaNodes.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using NoStringEvaluating.Nodes.Base;
-
-namespace NoStringEvaluating.Nodes.Common;
-
-///
-/// Formula nodes
-///
-public class FormulaNodes
-{
- ///
- /// Nodes
- ///
- public List Nodes { get; }
-
- ///
- /// Formula nodes
- ///
- public FormulaNodes(List nodes)
- {
- // I've removed ".AsReadOnly()" owing to the fact that it turned out to be slower then List ¯\_(ツ)_/¯
- // It was tested with Benchmark.One and Benchmark.Formula4. With AsReadOnly I got 300ms where as with List I got 200ms
- // Okay, if someone change collection it will be his mistake, let it be!
- Nodes = nodes;
- }
-
- ///
- /// ToString
- ///
- public override string ToString()
- {
- return string.Join(" ", Nodes);
- }
-}
diff --git a/README.md b/README.md
index 05ccfc8..42215ce 100644
--- a/README.md
+++ b/README.md
@@ -76,7 +76,7 @@ Compared with a good solution [mXparser](https://github.com/mariuszgromada/MathP
| 3 | 3 \* (9 / 456 \* (32 + 12)) / 17 - 3 |
| 4 | (2 + 6 - (13 \* 24 + 5 / (123 - 364 + 23))) - (2 + 6 - (13 \* 24 + 5 / (123 - 364 + 23))) + (2 + 6 - (13 \* 24 + 5 / (123 - 364 + 23))) \* 345 \* ((897 - 323)/ 23) |
| 5 | Arg1 \* Arg2 + Arg3 - Arg4 |
-| 6 | Arg1 \* (Arg2 + Arg3) - Arg4 / (Arg5 - Arg6) + 45 \* Arg7 + ((Arg8 \* 56 + (12 + Arg9))) - Arg10 |
+| 6 | Arg1 \* (Arg2 + Arg3) - Arg4 / (Arg5 - Arg6 + 1) + 45 \* Arg7 + ((Arg8 \* 56 + (12 + Arg9))) - Arg10 |
| 7 | add(1; 2; 3) |
| 8 | add(add(5; 1) - add(5; 2; 3)) |
| 9 | if(Arg1 > 0; add(56 + 9 / 12 \* 123.596; or(78; 9; 5; 2; 4; 5; 8; 7); 45;5); 9) \* 24 + 52 -33 |
@@ -84,18 +84,18 @@ Compared with a good solution [mXparser](https://github.com/mariuszgromada/MathP
### 1 000 000 calculations
Less is better
-
-
+
+
### Benchmark results
-
+
### Conclusion
As you can see this solution is faster in all cases, furthermore there isn't any garbage collection.
-Benchmark code - [ConsoleApp/Benchmark/BenchmarkNumberService.cs](ConsoleApp/Benchmark/BenchmarkNumberService.cs "ConsoleApp/Benchmark/BenchmarkNumberService.cs")
+Benchmark code - [src/ConsoleApp/Benchmark/BenchNumbers.cs](src/ConsoleApp/Benchmark/BenchNumbers.cs "src/ConsoleApp/Benchmark/BenchNumbers.cs")
-Benchmark excel - [BenchResults/Benchmark.xlsx](BenchResults/Benchmark.xlsx "BenchResults/Benchmark.xlsx")
+Benchmark excel - [benchResults/Benchmark.xlsx](benchResults/Benchmark.xlsx "benchResults/Benchmark.xlsx")
## Quick start
### Initialization
diff --git a/benchResults/Benchmark.xlsx b/benchResults/Benchmark.xlsx
new file mode 100644
index 0000000..9187ce0
Binary files /dev/null and b/benchResults/Benchmark.xlsx differ
diff --git a/benchResults/Both.html b/benchResults/Both.html
new file mode 100644
index 0000000..0ede071
--- /dev/null
+++ b/benchResults/Both.html
@@ -0,0 +1,55 @@
+
+
+
+
+ConsoleApp.Benchmark.BenchNumbers-20240817-115246
+
+
+
+
+
+BenchmarkDotNet v0.14.0, Windows 10 (10.0.19045.4780/22H2/2022Update)
+11th Gen Intel Core i7-1185G7 3.00GHz, 1 CPU, 8 logical and 4 physical cores
+.NET SDK 8.0.200
+ [Host] : .NET 8.0.2 (8.0.224.6711), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
+ Job-JNKMUS : .NET 8.0.2 (8.0.224.6711), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
+
+InvocationCount=3 IterationCount=10 RunStrategy=Monitoring
+UnrollFactor=1 WarmupCount=2
+
+
+
+Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
+
+Empty_NoString | 34.55 ms | 1.465 ms | 0.969 ms | - | - | - | 5.51 KB |
+
NumberOnly_NoString | 47.08 ms | 1.901 ms | 1.257 ms | - | - | - | 5.9 KB |
+
Formula1_NoString | 51.46 ms | 2.871 ms | 1.899 ms | - | - | - | 6.03 KB |
+
Formula2_NoString | 98.33 ms | 9.107 ms | 6.024 ms | - | - | - | 6.89 KB |
+
Formula3_NoString | 76.44 ms | 1.671 ms | 1.105 ms | - | - | - | 7.38 KB |
+
Formula4_NoString | 263.56 ms | 2.482 ms | 1.642 ms | - | - | - | 12.13 KB |
+
Formula5_NoString | 145.10 ms | 12.141 ms | 8.031 ms | - | - | - | 7.27 KB |
+
Formula6_NoString | 302.92 ms | 30.212 ms | 19.983 ms | - | - | - | 10.55 KB |
+
Formula7_NoString | 145.03 ms | 6.809 ms | 4.504 ms | - | - | - | 7.1 KB |
+
Formula8_NoString | 291.57 ms | 12.880 ms | 8.519 ms | - | - | - | 8.89 KB |
+
Formula9_NoString | 551.50 ms | 10.342 ms | 6.841 ms | - | - | - | 13.25 KB |
+
Formula10_NoString | 216.98 ms | 16.591 ms | 10.974 ms | - | - | - | 7.94 KB |
+
Empty_MxParser | 93.31 ms | 9.150 ms | 6.052 ms | 66000.0000 | - | - | 406250.92 KB |
+
NumberOnly_MxParser | 90.66 ms | 3.553 ms | 2.350 ms | 24000.0000 | - | - | 148515.66 KB |
+
Formula1_MxParser | 137.42 ms | 2.914 ms | 1.928 ms | 44333.3333 | - | - | 273522.6 KB |
+
Formula2_MxParser | 433.20 ms | 42.304 ms | 27.982 ms | 184666.6667 | 333.3333 | - | 1133044.61 KB |
+
Formula3_MxParser | 588.55 ms | 34.226 ms | 22.639 ms | 270333.3333 | 1000.0000 | - | 1656532.77 KB |
+
Formula4_MxParser | 2,367.88 ms | 155.146 ms | 102.619 ms | 1135000.0000 | 22333.3333 | - | 6954188.17 KB |
+
Formula5_MxParser | 276.39 ms | 6.087 ms | 4.026 ms | 99333.3333 | - | - | 609582.25 KB |
+
Formula6_MxParser | 1,104.95 ms | 68.355 ms | 45.213 ms | 539333.3333 | 4333.3333 | - | 3305396.21 KB |
+
Formula7_MxParser | 279.89 ms | 3.204 ms | 2.119 ms | 131333.3333 | - | - | 804815.08 KB |
+
Formula8_MxParser | 617.36 ms | 12.880 ms | 8.519 ms | 341666.6667 | 1666.6667 | - | 2094008.94 KB |
+
Formula9_MxParser | 7,669.47 ms | 98.175 ms | 64.937 ms | 1447666.6667 | 366000.0000 | 5666.6667 | 9360854.98 KB |
+
Formula10_MxParser | 626.87 ms | 7.463 ms | 4.937 ms | 247333.3333 | 666.6667 | - | 1515840.71 KB |
+
+
+
diff --git a/images/Both.png b/images/Both.png
new file mode 100644
index 0000000..1c19e63
Binary files /dev/null and b/images/Both.png differ
diff --git a/images/Graph.png b/images/Graph.png
new file mode 100644
index 0000000..ccb489b
Binary files /dev/null and b/images/Graph.png differ
diff --git a/images/Table.png b/images/Table.png
new file mode 100644
index 0000000..7a82457
Binary files /dev/null and b/images/Table.png differ
diff --git a/ConsoleApp/Benchmark/Base/BenchBase.cs b/src/ConsoleApp/Benchmark/Base/BenchBase.cs
similarity index 96%
rename from ConsoleApp/Benchmark/Base/BenchBase.cs
rename to src/ConsoleApp/Benchmark/Base/BenchBase.cs
index 0c6f0a5..ebfc6b5 100644
--- a/ConsoleApp/Benchmark/Base/BenchBase.cs
+++ b/src/ConsoleApp/Benchmark/Base/BenchBase.cs
@@ -23,20 +23,20 @@ public abstract class BenchBase
[GlobalSetup]
public virtual void Setup()
{
- _usedFunctions = new IFunction[]
- {
+ _usedFunctions =
+ [
new AddFunction(),
new IfFunction(),
new OrFunction(),
new Func_kov(),
new Func_kovt(),
- };
+ ];
- _usedFunctionsMxParser = new[]
- {
+ _usedFunctionsMxParser =
+ [
new Function("kov", new FExtension_kov()),
new Function("kovt", new FExtension_kovt()),
- };
+ ];
mXparser.disableAlmostIntRounding();
mXparser.disableUlpRounding();
@@ -139,7 +139,7 @@ private Expression CreateMxParser(string formula)
public const string Formula4 = "(2 + 6 - (13 * 24 + 5 / (123 - 364 + 23))) - (2 + 6 - (13 * 24 + 5 / (123 - 364 + 23))) + (2 + 6 - (13 * 24 + 5 / (123 - 364 + 23))) * 345 * ((897 - 323)/ 23)";
public const string Formula5 = $"{Arg1} * {Arg2} + {Arg3} - {Arg4}";
- public const string Formula6 = $"{Arg1} * ({Arg2} + {Arg3}) - {Arg4} / ({Arg5} - {Arg6}) + 45 * {Arg7} + (({Arg8} * 56 + (12 + {Arg9}))) - {Arg10}";
+ public const string Formula6 = $"{Arg1} * ({Arg2} + {Arg3}) - {Arg4} / ({Arg5} - {Arg6} + 1) + 45 * {Arg7} + (({Arg8} * 56 + (12 + {Arg9}))) - {Arg10}";
public const string Formula7 = $"add(1; 2; 3)";
public const string Formula8 = $"add(add(5; 1) - add(5; 2; 3))";
diff --git a/ConsoleApp/Benchmark/BenchNumbers.cs b/src/ConsoleApp/Benchmark/BenchNumbers.cs
similarity index 100%
rename from ConsoleApp/Benchmark/BenchNumbers.cs
rename to src/ConsoleApp/Benchmark/BenchNumbers.cs
diff --git a/ConsoleApp/Benchmark/BenchParallel.cs b/src/ConsoleApp/Benchmark/BenchParallel.cs
similarity index 100%
rename from ConsoleApp/Benchmark/BenchParallel.cs
rename to src/ConsoleApp/Benchmark/BenchParallel.cs
diff --git a/ConsoleApp/ConsoleApp.csproj b/src/ConsoleApp/ConsoleApp.csproj
similarity index 100%
rename from ConsoleApp/ConsoleApp.csproj
rename to src/ConsoleApp/ConsoleApp.csproj
diff --git a/ConsoleApp/NoStringNinjectModule.cs b/src/ConsoleApp/NoStringNinjectModule.cs
similarity index 100%
rename from ConsoleApp/NoStringNinjectModule.cs
rename to src/ConsoleApp/NoStringNinjectModule.cs
diff --git a/ConsoleApp/Program.cs b/src/ConsoleApp/Program.cs
similarity index 100%
rename from ConsoleApp/Program.cs
rename to src/ConsoleApp/Program.cs
diff --git a/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests.csproj b/src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests.csproj
similarity index 100%
rename from NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests.csproj
rename to src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests.csproj
diff --git a/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests/NoStringEvaluatorExtensionsTests.cs b/src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests/NoStringEvaluatorExtensionsTests.cs
similarity index 100%
rename from NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests/NoStringEvaluatorExtensionsTests.cs
rename to src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.Tests/NoStringEvaluatorExtensionsTests.cs
diff --git a/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.csproj b/src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.csproj
similarity index 100%
rename from NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.csproj
rename to src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.csproj
diff --git a/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.xml b/src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.xml
similarity index 100%
rename from NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.xml
rename to src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluating.Extensions.Microsoft.DependencyInjection.xml
diff --git a/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluatorExtensions.cs b/src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluatorExtensions.cs
similarity index 100%
rename from NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluatorExtensions.cs
rename to src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/NoStringEvaluatorExtensions.cs
diff --git a/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/logo.png b/src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/logo.png
similarity index 100%
rename from NoStringEvaluating.Extensions.Microsoft.DependencyInjection/logo.png
rename to src/NoStringEvaluating.Extensions.Microsoft.DependencyInjection/logo.png
diff --git a/NoStringEvaluating.Tests/NoStringEvaluating.Tests.csproj b/src/NoStringEvaluating.Tests/NoStringEvaluating.Tests.csproj
similarity index 77%
rename from NoStringEvaluating.Tests/NoStringEvaluating.Tests.csproj
rename to src/NoStringEvaluating.Tests/NoStringEvaluating.Tests.csproj
index e3b85f1..f0a633b 100644
--- a/NoStringEvaluating.Tests/NoStringEvaluating.Tests.csproj
+++ b/src/NoStringEvaluating.Tests/NoStringEvaluating.Tests.csproj
@@ -9,4 +9,8 @@
+
+
+
+
diff --git a/src/NoStringEvaluating.Tests/PerfTests/PerformanceTests.cs b/src/NoStringEvaluating.Tests/PerfTests/PerformanceTests.cs
new file mode 100644
index 0000000..486fcc2
--- /dev/null
+++ b/src/NoStringEvaluating.Tests/PerfTests/PerformanceTests.cs
@@ -0,0 +1,115 @@
+using System.Diagnostics;
+using NoStringEvaluating.Factories;
+using NoStringEvaluating.Functions.Base;
+using NoStringEvaluating.Functions.Logic;
+using NoStringEvaluating.Functions.Math;
+using NoStringEvaluating.Models.Values;
+using NoStringEvaluating.Tests.PerfTests.Report;
+using NUnit.Framework;
+
+namespace NoStringEvaluating.Tests.PerfTests;
+
+[NonParallelizable]
+[Category("PerfTests")]
+[Explicit("These tests are only run when explicitly specified")]
+internal class PerformanceTests
+{
+ private NoStringEvaluator.Facade _serviceFacade;
+ private ReportContainer _report;
+
+ [OneTimeSetUp]
+ public void GlobalSetup()
+ {
+ _report = new();
+ }
+
+ [OneTimeTearDown]
+ public void GlobalTeardown()
+ {
+ ReportWriter.Write(_report);
+ }
+
+ [SetUp]
+ public void Setup()
+ {
+ var functions = new IFunction[]
+ {
+ new AddFunction(),
+ new IfFunction(),
+ new OrFunction(),
+ new Func_kov(),
+ new Func_kovt(),
+ };
+
+ _serviceFacade = NoStringEvaluator.CreateFacade(cfg => cfg.WithoutDefaultFunctions().WithFunctions(functions));
+ }
+
+ [TestCaseSource(nameof(RunSource))]
+ public void RunFormula(string formulaName, string formula, IDictionary args, long targetElapsedMilliseconds)
+ {
+ // arrange
+ var n = 1_000_000;
+
+ var nodes = _serviceFacade.FormulaCache.GetFormulaNodes(formula);
+
+ // act, assert
+ var res = _serviceFacade.Evaluator.CalcNumber(nodes, args);
+
+ var ela = Stopwatch.StartNew();
+ for (var i = 0; i < n; i++)
+ {
+ _ = _serviceFacade.Evaluator.Calc(nodes, args);
+ }
+
+ ela.Stop();
+
+ _report.Append(formulaName, res, ela.ElapsedMilliseconds, targetElapsedMilliseconds);
+ }
+
+ private static IEnumerable