Skip to content

Commit d0b61ec

Browse files
committed
Factorial and Catalan methods updated to be the most efficient possible. MathBenchmarks refactoring.
1 parent 902b648 commit d0b61ec

File tree

2 files changed

+162
-177
lines changed

2 files changed

+162
-177
lines changed

csharp/Platform.Numbers.Benchmarks/MathBenchmarks.cs

Lines changed: 133 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,54 +6,170 @@ namespace Platform.Numbers.Benchmarks
66
[MemoryDiagnoser]
77
public class MathBenchmarks
88
{
9-
private const int FACTORIALTESTNUMBER = 19;
9+
private class Alternatives
10+
{
11+
/// <remarks>
12+
/// <para>Source: https://oeis.org/A000142/list </para>
13+
/// <para>Источник: https://oeis.org/A000142/list </para>
14+
/// </remarks>
15+
private static readonly ulong[] _factorials =
16+
{
17+
1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800,
18+
479001600, 6227020800, 87178291200, 1307674368000, 20922789888000,
19+
355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000,
20+
};
21+
22+
public static ulong FactorialUsingStaticArrayAndRecursionWithContantAsMaximumN(ulong n)
23+
{
24+
if (n <= 1)
25+
{
26+
return 1;
27+
}
28+
if (n < 21)
29+
{
30+
return _factorials[n];
31+
}
32+
return n * FactorialUsingStaticArrayAndRecursionWithContantAsMaximumN(n - 1);
33+
}
34+
35+
public static ulong FactorialUsingStaticArrayAndRecursionWithArrayLengthFieldAsMaximumN(ulong n)
36+
{
37+
if (n <= 1)
38+
{
39+
return 1;
40+
}
41+
if (n < (ulong)_factorials.Length)
42+
{
43+
return _factorials[n];
44+
}
45+
return n * FactorialUsingStaticArrayAndRecursionWithArrayLengthFieldAsMaximumN(n - 1);
46+
}
47+
48+
public static ulong FactorialWithDirectArrayAccess(ulong n)
49+
{
50+
return _factorials[n];
51+
}
52+
53+
public static ulong FactorialOf19()
54+
{
55+
return 121645100408832000;
56+
}
57+
58+
public static ulong ConditionSeries(ulong n)
59+
{
60+
if (n < 0)
61+
return 0;
62+
if (n == 0)
63+
return 1;
64+
if (n == 1 || n == 2)
65+
return 1;
66+
if (n == 3) return 2;
67+
if (n == 4) return 6;
68+
if (n == 5) return 24;
69+
if (n == 6) return 120;
70+
if (n == 7) return 720;
71+
if (n == 8) return 5040;
72+
if (n == 9) return 40320;
73+
if (n == 10) return 362880;
74+
if (n == 11) return 3628800;
75+
if (n == 12) return 39916800;
76+
if (n == 13) return 479001600;
77+
if (n == 14) return 6227020800;
78+
if (n == 15) return 87178291200;
79+
if (n == 16) return 1307674368000;
80+
if (n == 17) return 20922789888000;
81+
if (n == 18) return 355687428096000;
82+
if (n == 19) return 6402373705728000;
83+
if (n == 20) return 121645100408832000;
84+
if (n == 21) return 2432902008176640000;
85+
return n * ConditionSeries(n - 1);
86+
}
87+
88+
public static ulong FactorialWhileLoopWithArray(ulong n)
89+
{
90+
ulong[] _facts =
91+
{
92+
1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800,
93+
479001600, 6227020800, 87178291200, 1307674368000, 20922789888000,
94+
355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000,
95+
};
96+
if (n < (ulong)_facts.Length) return _facts[n];
97+
ulong r = n;
98+
while (n > 1) r *= --n;
99+
return r;
100+
}
101+
102+
public static ulong FactorialWhileLoopWithoutArray(ulong n)
103+
{
104+
if (n < (ulong)_factorials.Length) return _factorials[n];
105+
ulong r = n;
106+
while (n > 1) r *= --n;
107+
return r;
108+
}
109+
110+
public static ulong FactorialWhileLoopWithoutArrayAndCountingArrayLength(ulong n)
111+
{
112+
if (n < 21) return _factorials[n];
113+
ulong r = n;
114+
while (n > 1) r *= --n;
115+
return r;
116+
}
117+
}
118+
119+
private const ulong FactorialNumber = 19;
120+
121+
[Benchmark]
122+
public ulong CurrentFactorialImplementation()
123+
{
124+
return Math.Factorial(FactorialNumber);
125+
}
10126

11127
[Benchmark]
12-
public long FactorialUsingRecursion()
128+
public ulong FactorialUsingStaticArrayAndRecursionWithContantAsMaximumN()
13129
{
14-
return Math.Factorial(FACTORIALTESTNUMBER);
130+
return Alternatives.FactorialUsingStaticArrayAndRecursionWithContantAsMaximumN(FactorialNumber);
15131
}
16132

17133
[Benchmark]
18-
public long FactorialRecursionCountingArraylength()
134+
public ulong FactorialUsingStaticArrayAndRecursionWithArrayLengthFieldAsMaximumN()
19135
{
20-
return Math.FactorialRecursionCountingArraylength(FACTORIALTESTNUMBER);
136+
return Alternatives.FactorialUsingStaticArrayAndRecursionWithArrayLengthFieldAsMaximumN(FactorialNumber);
21137
}
22138

23139
[Benchmark]
24-
public long FactorialUsingFactTree()
140+
public ulong FactorialUsingFactTree()
25141
{
26-
return Math.FactTree(FACTORIALTESTNUMBER);
142+
return Alternatives.ConditionSeries(FactorialNumber);
27143
}
28144

29145
[Benchmark]
30-
public long FactorialOnly21()
146+
public ulong FactorialOnly21()
31147
{
32-
return Math.FactorialOnly21(FACTORIALTESTNUMBER);
148+
return Alternatives.FactorialWithDirectArrayAccess(FactorialNumber);
33149
}
34150

35151
[Benchmark]
36-
public long FactorialOf19()
152+
public ulong FactorialOf19()
37153
{
38-
return Math.FactorialOf19(FACTORIALTESTNUMBER);
154+
return Alternatives.FactorialOf19();
39155
}
40156

41157
[Benchmark]
42-
public long FactorialWhileWithArray()
158+
public ulong FactorialWhileWithArray()
43159
{
44-
return Math.FactorialWhileWithArray(FACTORIALTESTNUMBER);
160+
return Alternatives.FactorialWhileLoopWithArray(FactorialNumber);
45161
}
46162

47163
[Benchmark]
48-
public long FactorialWhileWithoutArray()
164+
public ulong FactorialWhileWithoutArray()
49165
{
50-
return Math.FactorialWhileWithoutArray(FACTORIALTESTNUMBER);
166+
return Alternatives.FactorialWhileLoopWithoutArray(FactorialNumber);
51167
}
52168

53169
[Benchmark]
54-
public long FactorialWhileWithoutArrayAndCountingArrayLength()
170+
public ulong FactorialWhileWithoutArrayAndCountingArrayLength()
55171
{
56-
return Math.FactorialWhileWithoutArrayAndCountingArrayLength(FACTORIALTESTNUMBER);
172+
return Alternatives.FactorialWhileLoopWithoutArrayAndCountingArrayLength(FactorialNumber);
57173
}
58174
}
59175
}

0 commit comments

Comments
 (0)