Skip to content

Commit 2e722cc

Browse files
authored
Improve performance of hex string parsing in SKColor (#2467)
1 parent 6db9696 commit 2e722cc

File tree

1 file changed

+60
-9
lines changed

1 file changed

+60
-9
lines changed

binding/Binding/SKColor.cs

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,29 +133,79 @@ public static bool TryParse (string hexString, out SKColor color)
133133
return false;
134134
}
135135

136+
#if NETCOREAPP3_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
136137
// clean up string
137-
hexString = hexString.Trim ().ToUpperInvariant ();
138-
if (hexString[0] == '#')
139-
hexString = hexString.Substring (1);
138+
var hexSpan = hexString.AsSpan ().Trim ().TrimStart ('#');
140139

141-
var len = hexString.Length;
140+
var len = hexSpan.Length;
142141
if (len == 3 || len == 4) {
143142
byte a;
144143
// parse [A]
145144
if (len == 4) {
146-
if (!byte.TryParse (string.Concat (hexString[len - 4], hexString[len - 4]), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out a)) {
145+
if (!byte.TryParse (hexSpan.Slice (0, 1), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out a)) {
147146
// error
148147
color = SKColor.Empty;
149148
return false;
150149
}
150+
a = (byte)(a << 4 | a);
151151
} else {
152152
a = 255;
153153
}
154154

155155
// parse RGB
156-
if (!byte.TryParse (string.Concat (hexString[len - 3], hexString[len - 3]), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var r) ||
157-
!byte.TryParse (string.Concat (hexString[len - 2], hexString[len - 2]), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var g) ||
158-
!byte.TryParse (string.Concat (hexString[len - 1], hexString[len - 1]), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var b)) {
156+
if (!byte.TryParse (hexSpan.Slice (len - 3, 1), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var r) ||
157+
!byte.TryParse (hexSpan.Slice (len - 2, 1), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var g) ||
158+
!byte.TryParse (hexSpan.Slice (len - 1, 1), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var b)) {
159+
// error
160+
color = SKColor.Empty;
161+
return false;
162+
}
163+
164+
// success
165+
color = new SKColor ((byte)(r << 4 | r), (byte)(g << 4 | g), (byte)(b << 4 | b), a);
166+
return true;
167+
}
168+
169+
if (len == 6 || len == 8) {
170+
// parse [AA]RRGGBB
171+
if (!uint.TryParse (hexSpan, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var number)) {
172+
// error
173+
color = SKColor.Empty;
174+
return false;
175+
}
176+
177+
// success
178+
color = (SKColor)number;
179+
180+
// alpha was not provided, so use 255
181+
if (len == 6) {
182+
color = color.WithAlpha (255);
183+
}
184+
return true;
185+
}
186+
#else
187+
// clean up string
188+
hexString = hexString.Trim ();
189+
var startIndex = hexString[0] == '#' ? 1 : 0;
190+
191+
var len = hexString.Length - startIndex;
192+
if (len == 3 || len == 4) {
193+
byte a;
194+
// parse [A]
195+
if (len == 4) {
196+
if (!byte.TryParse (string.Concat (new string (hexString[len - 4 + startIndex], 2)), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out a)) {
197+
// error
198+
color = SKColor.Empty;
199+
return false;
200+
}
201+
} else {
202+
a = 255;
203+
}
204+
205+
// parse RGB
206+
if (!byte.TryParse (new string (hexString[len - 3 + startIndex], 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var r) ||
207+
!byte.TryParse (new string (hexString[len - 2 + startIndex], 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var g) ||
208+
!byte.TryParse (new string (hexString[len - 1 + startIndex], 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var b)) {
159209
// error
160210
color = SKColor.Empty;
161211
return false;
@@ -168,7 +218,7 @@ public static bool TryParse (string hexString, out SKColor color)
168218

169219
if (len == 6 || len == 8) {
170220
// parse [AA]RRGGBB
171-
if (!uint.TryParse (hexString, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var number)) {
221+
if (!uint.TryParse (hexString.Substring (startIndex), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var number)) {
172222
// error
173223
color = SKColor.Empty;
174224
return false;
@@ -183,6 +233,7 @@ public static bool TryParse (string hexString, out SKColor color)
183233
}
184234
return true;
185235
}
236+
#endif
186237

187238
// error
188239
color = SKColor.Empty;

0 commit comments

Comments
 (0)