Skip to content

Commit 90657af

Browse files
author
Petr Sramek
committed
another huge POC commit
1 parent bfb93b1 commit 90657af

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1280
-908
lines changed

PolylineAlgorithm.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{02EA
1818
EndProject
1919
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.IO.Pipelines", "src\PolylineAlgorithm.IO.Pipelines\PolylineAlgorithm.IO.Pipelines.csproj", "{AC2D1BF7-B70C-461A-92FB-2C1E50D6C5FB}"
2020
EndProject
21+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolylineAlgorithm.Comparison.Benchmarks", "benchmarks\PolylineAlgorithm.Comparison.Benchmarks\PolylineAlgorithm.Comparison.Benchmarks.csproj", "{5E66392A-23C5-41BA-A5E7-E3CA097E3C91}"
22+
EndProject
2123
Global
2224
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2325
Debug|Any CPU = Debug|Any CPU
@@ -40,6 +42,10 @@ Global
4042
{AC2D1BF7-B70C-461A-92FB-2C1E50D6C5FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
4143
{AC2D1BF7-B70C-461A-92FB-2C1E50D6C5FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
4244
{AC2D1BF7-B70C-461A-92FB-2C1E50D6C5FB}.Release|Any CPU.Build.0 = Release|Any CPU
45+
{5E66392A-23C5-41BA-A5E7-E3CA097E3C91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
46+
{5E66392A-23C5-41BA-A5E7-E3CA097E3C91}.Debug|Any CPU.Build.0 = Debug|Any CPU
47+
{5E66392A-23C5-41BA-A5E7-E3CA097E3C91}.Release|Any CPU.ActiveCfg = Release|Any CPU
48+
{5E66392A-23C5-41BA-A5E7-E3CA097E3C91}.Release|Any CPU.Build.0 = Release|Any CPU
4349
EndGlobalSection
4450
GlobalSection(SolutionProperties) = preSolution
4551
HideSolutionNode = FALSE
@@ -49,6 +55,7 @@ Global
4955
{30324A08-AA42-425D-87DA-8F9C6AF60454} = {576FEFFC-B624-40C3-A8AF-4E5233802EA0}
5056
{9C7CBAD5-415B-4589-86E1-01C849F9C56C} = {33C03F16-4313-4579-87E6-65892AF21D7D}
5157
{AC2D1BF7-B70C-461A-92FB-2C1E50D6C5FB} = {51C886AF-D610-48A4-9D73-2DEB38742801}
58+
{5E66392A-23C5-41BA-A5E7-E3CA097E3C91} = {33C03F16-4313-4579-87E6-65892AF21D7D}
5259
EndGlobalSection
5360
GlobalSection(ExtensibilityGlobals) = postSolution
5461
SolutionGuid = {93A268DC-0947-4FBB-B495-DDAD4B013D82}

benchmarks/PolylineAlgorithm.Benchmarks/AsyncReadWriteBenchmark.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// using System.Buffers;
77
// using System.Collections.Generic;
88
// using System.IO;
9+
// using System.IO.Pipelines;
910
// using System.Text.Json;
1011
// using System.Text.Json.Serialization.Metadata;
1112

@@ -85,7 +86,7 @@
8586
// var polyline = Encoder.Encode(BlockingEnumeration);
8687

8788
// await writer
88-
// .WriteAsync(polyline.AsMemory());
89+
// .WriteAsync(polyline.AsSequence());
8990
// await writer
9091
// .FlushAsync();
9192
// }
@@ -107,7 +108,7 @@
107108

108109
// using StreamWriter writer = new(file);
109110

110-
// var reader = new SequenceReader<char>(new(polyline.AsMemory()));
111+
// var reader = new SequenceReader<char>(polyline.AsSequence());
111112

112113
// long index = 0;
113114

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace PolylineAlgorithm.Benchmarks.Internal;
2+
3+
using PolylineAlgorithm.Abstraction;
4+
5+
internal class CoordinateFactory : ICoordinateFactory<Coordinate> {
6+
public Coordinate Create(double latitude, double longitude) {
7+
return new Coordinate(latitude, longitude);
8+
}
9+
}

benchmarks/PolylineAlgorithm.Benchmarks/Internal/ValueProvider.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
namespace PolylineAlgorithm.Benchmarks.Internal
2-
{
1+
namespace PolylineAlgorithm.Benchmarks.Internal {
32
using System.Collections.Concurrent;
43

5-
public static class ValueProvider
6-
{
4+
public static class ValueProvider {
75
private static readonly ConcurrentDictionary<int, CoordinatePair> _cache = new();
86
private static readonly PolylineEncoder _encoder = new();
97

@@ -26,19 +24,20 @@ private static CoordinatePair GetCaheEntry(int count) {
2624

2725
var enumeration = Enumerable
2826
.Range(0, count)
29-
.Select(i => new Coordinate(RandomLatitude(), RandomLongitude()));
27+
.Select(i => new Coordinate(RandomLatitude(), RandomLongitude()))
28+
.ToList();
3029

3130
entry = _cache.GetOrAdd(count, _ => new CoordinatePair(enumeration, _encoder.Encode(enumeration)));
3231

3332
return entry;
3433
}
3534

3635
private static double RandomLongitude() {
37-
return Random.Shared.Next(-180, 180) + Random.Shared.NextDouble();
36+
return Math.Round(Random.Shared.Next(-180, 180) + Random.Shared.NextDouble(), 5);
3837
}
3938

4039
private static double RandomLatitude() {
41-
return Random.Shared.Next(-90, 90) + Random.Shared.NextDouble();
40+
return Math.Round(Random.Shared.Next(-90, 90) + Random.Shared.NextDouble(), 5);
4241
}
4342

4443
private readonly struct CoordinatePair {
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
//
2+
// Copyright © Pete Sramek. All rights reserved.
3+
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
4+
//
5+
6+
namespace PolylineAlgorithm.Benchmarks;
7+
8+
using BenchmarkDotNet.Attributes;
9+
using BenchmarkDotNet.Engines;
10+
using PolylineAlgorithm;
11+
using PolylineAlgorithm.Benchmarks.Internal;
12+
using System.Text;
13+
14+
/// <summary>
15+
/// Benchmarks for the <see cref="Polyline"/> struct.
16+
/// </summary>
17+
[RankColumn]
18+
public class PolylineBenchmark {
19+
private static readonly Consumer consumer = new();
20+
21+
[Params(1, 10, 100, 1_000, 10_000, 100_000, 1_000_000)]
22+
public int Length;
23+
24+
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
25+
/// <summary>
26+
/// Gets the string value representing the encoded polyline.
27+
/// </summary>
28+
public string StringValue { get; private set; }
29+
30+
/// <summary>
31+
/// Gets the character array representing the encoded polyline.
32+
/// </summary>
33+
public byte[] ByteArray { get; private set; }
34+
35+
/// <summary>
36+
/// Gets the read-only memory representing the encoded polyline.
37+
/// </summary>
38+
public ReadOnlyMemory<byte> Memory { get; private set; }
39+
40+
/// <summary>
41+
/// Gets the read-only memory representing the encoded polyline.
42+
/// </summary>
43+
public Polyline Polyline { get; private set; }
44+
45+
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
46+
47+
48+
/// <summary>
49+
/// Sets up the data for the benchmarks.
50+
/// </summary>
51+
[GlobalSetup]
52+
public void SetupData() {
53+
Polyline = ValueProvider.GetPolyline(Length);
54+
StringValue = Polyline.ToString();
55+
ByteArray = Encoding.UTF8.GetBytes(StringValue);
56+
Memory = ByteArray.AsMemory();
57+
}
58+
59+
/// <summary>
60+
/// Benchmarks the encoding of a list of coordinates into a polyline.
61+
/// </summary>
62+
/// <returns>The encoded polyline.</returns>
63+
[Benchmark]
64+
public Polyline Polyline_FromString() {
65+
var polyline = Polyline
66+
.FromString(StringValue);
67+
68+
return polyline;
69+
}
70+
71+
/// <summary>
72+
/// Benchmarks the encoding of an enumeration of coordinates into a polyline.
73+
/// </summary>
74+
/// <returns>The encoded polyline.</returns>
75+
[Benchmark]
76+
public Polyline Polyline_FromCharArray() {
77+
var polyline = Polyline
78+
.FromByteArray(ByteArray);
79+
80+
return polyline;
81+
}
82+
83+
/// <summary>
84+
/// Benchmarks the encoding of an enumeration of coordinates into a polyline.
85+
/// </summary>
86+
/// <returns>The encoded polyline.</returns>
87+
[Benchmark]
88+
public Polyline Polyline_FromMemory() {
89+
var polyline = Polyline
90+
.FromMemory(Memory);
91+
92+
return polyline;
93+
}
94+
95+
/// <summary>
96+
/// Benchmarks the encoding of an enumeration of coordinates into a polyline.
97+
/// </summary>
98+
/// <returns>The encoded polyline.</returns>
99+
[Benchmark]
100+
public string Polyline_ToString() {
101+
var stringValue = Polyline
102+
.ToString();
103+
104+
return stringValue;
105+
}
106+
107+
/// <summary>
108+
/// Benchmarks the encoding of an enumeration of coordinates into a polyline.
109+
/// </summary>
110+
/// <returns>The encoded polyline.</returns>
111+
[Benchmark]
112+
public long Polyline_GetCoordinateCount() {
113+
var coordinateCount = Polyline
114+
.GetCoordinateCount();
115+
116+
return coordinateCount;
117+
}
118+
119+
120+
/// <summary>
121+
/// Benchmarks the encoding of an enumeration of coordinates into a polyline.
122+
/// </summary>
123+
/// <returns>The encoded polyline.</returns>
124+
[Benchmark]
125+
public void Polyline_CopyTo() {
126+
var destination = new byte[Polyline.Length];
127+
128+
Polyline
129+
.CopyTo(destination);
130+
131+
destination
132+
.Consume(consumer);
133+
}
134+
135+
/// <summary>
136+
/// Benchmarks the encoding of an enumeration of coordinates into a polyline.
137+
/// </summary>
138+
/// <returns>The encoded polyline.</returns>
139+
[Benchmark]
140+
public bool Polyline_Equals() {
141+
var equals = Polyline
142+
.Equals(Polyline);
143+
144+
return equals;
145+
}
146+
}

benchmarks/PolylineAlgorithm.Benchmarks/PolylineDecoderBenchmark.cs

Lines changed: 27 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace PolylineAlgorithm.Benchmarks;
88
using BenchmarkDotNet.Attributes;
99
using BenchmarkDotNet.Engines;
1010
using PolylineAlgorithm;
11+
using PolylineAlgorithm.Abstraction;
1112
using PolylineAlgorithm.Benchmarks.Internal;
1213
using System.Text;
1314

@@ -30,35 +31,28 @@ public class PolylineDecoderBenchmark {
3031
/// <summary>
3132
/// Gets the character array representing the encoded polyline.
3233
/// </summary>
33-
public char[] CharArray { get; private set; }
34-
3534
public byte[] ByteArray { get; private set; }
3635

3736
/// <summary>
3837
/// Gets the read-only memory representing the encoded polyline.
3938
/// </summary>
4039
public ReadOnlyMemory<byte> Memory { get; private set; }
40+
4141
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
4242

4343
/// <summary>
4444
/// The polyline decoder instance.
4545
/// </summary>
46-
public PolylineDecoder Decoder = new();
47-
48-
/// <summary>
49-
/// The async polyline decoder instance.
50-
/// </summary>
51-
//public AsyncPolylineDecoder AsyncDecoder = new();
46+
public PolylineDecoder<Coordinate> Decoder = new(new CoordinateFactory());
5247

5348
/// <summary>
5449
/// Sets up the data for the benchmarks.
5550
/// </summary>
5651
[GlobalSetup]
5752
public void SetupData() {
5853
StringValue = ValueProvider.GetPolyline(N).ToString();
59-
CharArray = StringValue.ToCharArray();
6054
ByteArray = Encoding.UTF8.GetBytes(StringValue);
61-
Memory = Encoding.UTF8.GetBytes(StringValue).AsMemory();
55+
Memory = ByteArray.AsMemory();
6256
}
6357

6458
/// <summary>
@@ -78,7 +72,7 @@ public void PolylineDecoder_Decode_FromString() {
7872
/// </summary>
7973
[Benchmark]
8074
public void PolylineDecoder_Decode_FromCharArray() {
81-
Polyline polyline = Polyline.FromCharArray(CharArray);
75+
Polyline polyline = Polyline.FromByteArray(ByteArray);
8276

8377
Decoder
8478
.Decode(polyline)
@@ -97,45 +91,26 @@ public void PolylineDecoder_Decode_FromMemory() {
9791
.Consume(_consumer);
9892
}
9993

100-
///// <summary>
101-
///// Benchmarks the decoding of a polyline from read-only memory.
102-
///// </summary>
103-
//[Benchmark]
104-
//public async Task PolylineDecoder_DecodeAsync_FromString() {
105-
// Polyline polyline = Polyline.FromString(StringValue);
106-
107-
// var result = AsyncDecoder
108-
// .DecodeAsync(polyline)
109-
// .ConfigureAwait(false);
110-
111-
// await foreach (var _ in result) { }
112-
//}
113-
114-
///// <summary>
115-
///// Benchmarks the decoding of a polyline from read-only memory.
116-
///// </summary>
117-
//[Benchmark]
118-
//public async Task PolylineDecoder_DecodeAsync_CharArray() {
119-
// Polyline polyline = Polyline.FromCharArray(CharArray);
120-
121-
// var result = AsyncDecoder
122-
// .DecodeAsync(polyline)
123-
// .ConfigureAwait(false);
124-
125-
// await foreach (var _ in result) { }
126-
//}
127-
128-
///// <summary>
129-
///// Benchmarks the decoding of a polyline from read-only memory.
130-
///// </summary>
131-
//[Benchmark]
132-
//public async Task PolylineDecoder_DecodeAsync_FromMemory() {
133-
// Polyline polyline = Polyline.FromMemory(Memory);
134-
135-
// var result = AsyncDecoder
136-
// .DecodeAsync(polyline)
137-
// .ConfigureAwait(false);
138-
139-
// await foreach (var _ in result) { }
140-
//}
94+
/// <summary>
95+
/// Benchmarks the decoding of a polyline from read-only memory.
96+
/// </summary>
97+
[Benchmark]
98+
public void PolylineReader_ReadToEnd_Local() {
99+
PolylineReader reader = new(StringValue);
100+
101+
var result = ReadToEnd(reader);
102+
103+
result
104+
.Consume(_consumer);
105+
106+
static IEnumerable<Coordinate> ReadToEnd(PolylineReader reader) {
107+
var result = new List<Coordinate>();
108+
109+
while (reader.Read()) {
110+
result.Add(new(reader.Latitude, reader.Longitude));
111+
}
112+
113+
return result;
114+
}
115+
}
141116
}

benchmarks/PolylineAlgorithm.Benchmarks/PolylineEncoderBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public class PolylineEncoderBenchmark {
4949
[GlobalSetup]
5050
public void SetupData() {
5151
Enumeration = ValueProvider.GetCoordinates(N);
52-
List = [..Enumeration];
52+
List = [.. Enumeration];
5353
AsyncEnumeration = GetAsyncEnumeration(Enumeration!);
5454
}
5555

0 commit comments

Comments
 (0)