diff --git a/Source/DataTypes/SvgPointCollection.cs b/Source/DataTypes/SvgPointCollection.cs index f51e80fbd..267e4d17d 100644 --- a/Source/DataTypes/SvgPointCollection.cs +++ b/Source/DataTypes/SvgPointCollection.cs @@ -3,6 +3,7 @@ using System.ComponentModel; using System.Globalization; using System.Text; +using Svg.Helpers; namespace Svg { @@ -44,8 +45,10 @@ public override string ToString() /// /// A class to convert string into instances. /// - internal class SvgPointCollectionConverter : TypeConverter + public class SvgPointCollectionConverter : TypeConverter { + private static readonly char[] SplitChars = new[] { ' ', '\t', '\n', '\r', ',' }; + /// /// Converts the given object to the type of this converter, using the specified context and culture information. /// @@ -60,18 +63,37 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c { if (value is string s) { - var coords = s.AsSpan().Trim(); - var state = new CoordinateParserState(ref coords); - var result = new SvgPointCollection(); - while (CoordinateParser.TryGetFloat(out var pointValue, ref coords, ref state)) - { - result.Add(new SvgUnit(SvgUnitType.User, pointValue)); - } - - return result; + return Parse(s.AsSpan()); } return base.ConvertFrom(context, culture, value); } + + public static SvgPointCollection Parse(ReadOnlySpan points) + { +#if false + var coords = points.Trim(); + var state = new CoordinateParserState(ref coords); + var result = new SvgPointCollection(); + while (CoordinateParser.TryGetFloat(out var pointValue, ref coords, ref state)) + { + result.Add(new SvgUnit(SvgUnitType.User, pointValue)); + } + return result; +#else + var collection = new SvgPointCollection(); + var splitChars = SplitChars.AsSpan(); + var parts = new StringSplitEnumerator(points, splitChars); + + foreach (var part in parts) + { + var partValue = part.Value; + var result = StringParser.ToFloat(ref partValue); + collection.Add(new SvgUnit(SvgUnitType.User, result)); + } + + return collection; +#endif + } } } diff --git a/Tests/Svg.Benchmark/README.md b/Tests/Svg.Benchmark/README.md index b35113066..83b3d707d 100644 --- a/Tests/Svg.Benchmark/README.md +++ b/Tests/Svg.Benchmark/README.md @@ -52,3 +52,9 @@ dotnet run -c Release -f netcoreapp3.1 -- -f '*SvgUnitCollectionConverter_*' ``` dotnet run -c Release -f netcoreapp3.1 -- -f '*SvgNumberCollectionConverter_*' ``` + +### Run `SvgPointCollectionConverter` Benchmarks + +``` +dotnet run -c Release -f netcoreapp3.1 -- -f '*SvgPointCollectionConverter_*' +``` diff --git a/Tests/Svg.Benchmark/SvgPointCollectionConverterBenchmarks.cs b/Tests/Svg.Benchmark/SvgPointCollectionConverterBenchmarks.cs new file mode 100644 index 000000000..b77cf9010 --- /dev/null +++ b/Tests/Svg.Benchmark/SvgPointCollectionConverterBenchmarks.cs @@ -0,0 +1,16 @@ +using System; +using System.Text; +using BenchmarkDotNet.Attributes; +using Svg; + +namespace Svg.Benchmark +{ + public class SvgPointCollectionConverterBenchmarks + { + [Benchmark] + public void SvgPointCollectionConverter_Parse() + { + SvgPointCollectionConverter.Parse("1.6,3.2 1.2,5".AsSpan()); + } + } +}