Skip to content

Commit bde87ee

Browse files
committed
Avoid Dictionary allocations in GetNotUniqueExponents
1 parent 29d9e0e commit bde87ee

File tree

1 file changed

+49
-7
lines changed

1 file changed

+49
-7
lines changed

QRCoder/QRCodeGenerator.cs

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#endif
55
using System.Collections;
66
using System.Collections.Generic;
7+
using System.Diagnostics;
78
using System.Globalization;
89
using System.Linq;
910
using System.Runtime.CompilerServices;
@@ -1017,12 +1018,13 @@ private static Polynom MultiplyAlphaPolynoms(Polynom polynomBase, Polynom polyno
10171018
}
10181019

10191020
// Identify and merge terms with the same exponent.
1020-
var toGlue = GetNotUniqueExponents(resultPolynom);
10211021
#if NETCOREAPP
1022+
var toGlue = GetNotUniqueExponents(resultPolynom, resultPolynom.Count <= 128 ? stackalloc int[128].Slice(0, resultPolynom.Count) : new int[resultPolynom.Count]);
10221023
var gluedPolynoms = toGlue.Length <= 128
10231024
? stackalloc PolynomItem[128].Slice(0, toGlue.Length)
10241025
: new PolynomItem[toGlue.Length];
10251026
#else
1027+
var toGlue = GetNotUniqueExponents(resultPolynom);
10261028
var gluedPolynoms = new PolynomItem[toGlue.Length];
10271029
#endif
10281030
var gluedPolynomsIndex = 0;
@@ -1042,7 +1044,11 @@ private static Polynom MultiplyAlphaPolynoms(Polynom polynomBase, Polynom polyno
10421044

10431045
// Remove duplicated exponents and add the corrected ones back.
10441046
for (int i = resultPolynom.Count - 1; i >= 0; i--)
1047+
#if NETCOREAPP
1048+
if (toGlue.Contains(resultPolynom[i].Exponent))
1049+
#else
10451050
if (Array.IndexOf(toGlue, resultPolynom[i].Exponent) >= 0)
1051+
#endif
10461052
resultPolynom.RemoveAt(i);
10471053
foreach (var polynom in gluedPolynoms)
10481054
resultPolynom.Add(polynom);
@@ -1052,20 +1058,55 @@ private static Polynom MultiplyAlphaPolynoms(Polynom polynomBase, Polynom polyno
10521058
return resultPolynom;
10531059

10541060
// Auxiliary function to identify exponents that appear more than once in the polynomial.
1055-
int[] GetNotUniqueExponents(Polynom list)
1061+
#if NETCOREAPP
1062+
static ReadOnlySpan<int> GetNotUniqueExponents(Polynom list, Span<int> buffer)
10561063
{
1057-
var dic = new Dictionary<int, bool>(list.Count);
1064+
Debug.Assert(list.Count == buffer.Length);
1065+
1066+
int idx = 0;
10581067
foreach (var row in list)
10591068
{
1060-
#if NETCOREAPP
1061-
if (dic.TryAdd(row.Exponent, false))
1062-
dic[row.Exponent] = true;
1069+
buffer[idx++] = row.Exponent;
1070+
}
1071+
1072+
buffer.Sort();
1073+
1074+
idx = 0;
1075+
int expCount = 0;
1076+
int last = buffer[0];
1077+
1078+
for (int i = 1; i < buffer.Length; ++i)
1079+
{
1080+
if (buffer[i] == last)
1081+
{
1082+
expCount++;
1083+
}
1084+
else
1085+
{
1086+
if (expCount > 0)
1087+
{
1088+
Debug.Assert(idx <= i - 1);
1089+
1090+
buffer[idx++] = last;
1091+
expCount = 0;
1092+
}
1093+
}
1094+
1095+
last = buffer[i];
1096+
}
1097+
1098+
return buffer.Slice(0, idx);
1099+
}
10631100
#else
1101+
static int[] GetNotUniqueExponents(Polynom list)
1102+
{
1103+
var dic = new Dictionary<int, bool>(list.Count);
1104+
foreach (var row in list)
1105+
{
10641106
if (!dic.ContainsKey(row.Exponent))
10651107
dic.Add(row.Exponent, false);
10661108
else
10671109
dic[row.Exponent] = true;
1068-
#endif
10691110
}
10701111

10711112
// Collect all exponents that appeared more than once.
@@ -1086,6 +1127,7 @@ int[] GetNotUniqueExponents(Polynom list)
10861127

10871128
return result;
10881129
}
1130+
#endif
10891131
}
10901132

10911133
/// <inheritdoc cref="IDisposable.Dispose"/>

0 commit comments

Comments
 (0)