Skip to content

Commit c88f791

Browse files
committed
Update benchmark and profiling code
1 parent 20276f7 commit c88f791

File tree

6 files changed

+1089
-155
lines changed

6 files changed

+1089
-155
lines changed

benchmarks/Benchmarks/Benchmarks.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<OutputType>Exe</OutputType>
55
<TargetFramework>net6.0</TargetFramework>
66
<Nullable>enable</Nullable>
7+
<ImplicitUsings>enable</ImplicitUsings>
78
</PropertyGroup>
89

910
<ItemGroup>
@@ -12,6 +13,7 @@
1213

1314
<ItemGroup>
1415
<ProjectReference Include="..\..\src\Elastic.Clients.Elasticsearch\Elastic.Clients.Elasticsearch.csproj" />
16+
<PackageReference Include="NEST" Version="7.16.0" />
1517
</ItemGroup>
1618

1719
</Project>

benchmarks/Benchmarks/Program.cs

Lines changed: 87 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -1,157 +1,98 @@
1-
using System.IO;
21
using BenchmarkDotNet.Attributes;
2+
using BenchmarkDotNet.Configs;
3+
using BenchmarkDotNet.Reports;
34
using BenchmarkDotNet.Running;
4-
using Dia2Lib;
55
using Elastic.Clients.Elasticsearch;
6-
using Elastic.Clients.Elasticsearch.Aggregations;
6+
using Elastic.Transport;
7+
using Nest;
8+
using System.Globalization;
9+
using System.Text;
10+
using System.Text.Json;
711

8-
namespace Benchmarks;
12+
var config = ManualConfig.Create(DefaultConfig.Instance);
13+
config.SummaryStyle = new SummaryStyle(CultureInfo.CurrentCulture, true, BenchmarkDotNet.Columns.SizeUnit.B, null);
914

10-
internal class Program
11-
{
12-
private static void Main() =>
13-
//var thing = new IndicesGetString() { NameCount = 3 };
14-
//thing.Setup();
15-
//thing.NaiveStringCreate();
16-
17-
_ = BenchmarkRunner.Run<SerialisePolymorphic>();
18-
}
15+
BenchmarkRunner.Run<Benchmarks.BulkIngest>(config);
1916

20-
21-
[MemoryDiagnoser]
22-
public class SerialisePolymorphic
17+
namespace Benchmarks
2318
{
24-
25-
private readonly AggregationContainer _container1 = new AggregationContainer(new MinAggregation("testing"));
26-
private readonly ElasticsearchClient _client = new ElasticsearchClient();
27-
28-
29-
private readonly Stream _stream = new MemoryStream();
30-
31-
[Benchmark]
32-
public void Reflection()
19+
[MemoryDiagnoser]
20+
public class BulkIngest
3321
{
34-
_stream.Position = 0;
35-
_client.RequestResponseSerializer.Serialize(_container1, _stream);
22+
//private static readonly List<SampleData> Data = Enumerable.Range(0, 100).Select(r => new SampleData()).ToList();
23+
24+
private static readonly ElasticClient NestClient = new(new ConnectionSettings(new Uri("https://localhost:9600"))
25+
.BasicAuthentication("elastic", "c236sjjbMP3nUGDxU_Z6")
26+
.ServerCertificateValidationCallback((a, b, c, d) => true)
27+
.EnableApiVersioningHeader());
28+
29+
private static readonly ElasticsearchClient AlphaClient = new(new ElasticsearchClientSettings(new Uri("https://localhost:9600"))
30+
.Authentication(new BasicAuthentication("elastic", "c236sjjbMP3nUGDxU_Z6"))
31+
.ServerCertificateValidationCallback((a, b, c, d) => true));
32+
33+
private static readonly MemoryStream Stream = new(Encoding.UTF8.GetBytes(@"{""cluster_name"":""my-test-cluster"",""status"":""yellow"",""timed_out"":false,""number_of_nodes"":1,""number_of_data_nodes"":1,""active_primary_shards"":6,""active_shards"":6,""relocating_shards"":0,""initializing_shards"":0,""unassigned_shards"":4,""delayed_unassigned_shards"":0,""number_of_pending_tasks"":0,""number_of_in_flight_fetch"":0,""task_max_waiting_in_queue_millis"":0,""active_shards_percent_as_number"":60.0}"));
34+
35+
[Benchmark]
36+
public void Version7()
37+
{
38+
Stream.Position = 0;
39+
_ = NestClient.RequestResponseSerializer.Deserialize<Elastic.Clients.Elasticsearch.Cluster.ClusterHealthResponse>(Stream);
40+
}
41+
42+
[Benchmark]
43+
public void Version8()
44+
{
45+
Stream.Position = 0;
46+
_ = AlphaClient.RequestResponseSerializer.Deserialize<Elastic.Clients.Elasticsearch.Cluster.ClusterHealthResponse>(Stream);
47+
}
48+
49+
[Benchmark]
50+
public void Version8_String()
51+
{
52+
Stream.Position = 0;
53+
_ = AlphaClient.RequestResponseSerializer.Deserialize<Elastic.Clients.Elasticsearch.Cluster.ClusterHealthResponseV2>(Stream);
54+
}
55+
56+
//[Benchmark]
57+
//public void Version8_String_Converter()
58+
//{
59+
// Stream.Position = 0;
60+
// _ = AlphaClient.RequestResponseSerializer.Deserialize<Elastic.Clients.Elasticsearch.Cluster.ClusterHealthResponseV3>(Stream);
61+
//}
62+
63+
//[Benchmark]
64+
//public void Version8_String_ConverterWithBool()
65+
//{
66+
// Stream.Position = 0;
67+
// _ = AlphaClient.RequestResponseSerializer.Deserialize<Elastic.Clients.Elasticsearch.Cluster.ClusterHealthResponseV3_BoolFlags>(Stream);
68+
//}
69+
70+
//[Benchmark]
71+
//public void Version8_String_ConverterWithSpan()
72+
//{
73+
// Stream.Position = 0;
74+
// _ = AlphaClient.RequestResponseSerializer.Deserialize<Elastic.Clients.Elasticsearch.Cluster.ClusterHealthResponseV3_Span>(Stream);
75+
//}
76+
77+
//[Benchmark]
78+
//public void Version8_SourceWithoutUsingContext()
79+
//{
80+
// Stream.Position = 0;
81+
// _ = AlphaClient.RequestResponseSerializer.Deserialize<Elastic.Clients.Elasticsearch.Cluster.ClusterHealthResponseV4>(Stream);
82+
//}
83+
84+
//[Benchmark]
85+
//public void Version8_SourceDirect()
86+
//{
87+
// Stream.Position = 0;
88+
// _ = JsonSerializer.Deserialize(Stream, Elastic.Clients.Elasticsearch.Cluster.ClusterHealthResponseV4Context.Default.ClusterHealthResponseV4);
89+
//}
3690
}
91+
92+
public class SampleData
93+
{
94+
public SampleData() => Value = Guid.NewGuid();
3795

96+
public Guid Value { get; }
97+
}
3898
}
39-
40-
//[MemoryDiagnoser]
41-
//public class IndicesGetString
42-
//{
43-
// private readonly List<IndexName> _indices = new();
44-
45-
// private string _output = string.Empty;
46-
47-
// private readonly ElasticsearchClientSettings _settings = new();
48-
49-
// [Params(1,3)]
50-
// public int NameCount { get; set; }
51-
52-
// [GlobalSetup]
53-
// public void Setup()
54-
// {
55-
// for (var i = 0; i < NameCount; i++)
56-
// {
57-
// _indices.Add($"item{i}");
58-
// }
59-
// }
60-
61-
// [Benchmark(Baseline = true)]
62-
// public void StringJoin()
63-
// {
64-
// var indices = _indices.Select(i => i.GetString(_settings)).Distinct();
65-
// _output = string.Join(',', indices);
66-
// }
67-
68-
// [Benchmark]
69-
// public void NaiveStringCreate()
70-
// {
71-
// // This implementation doesn't ensure distinct values
72-
// // Is that really an issue as it's unlikely and would still be a valid request?
73-
74-
// // Issue: This doesn't call the Inferrer so is not a fair test since we'd
75-
76-
// var length = 0;
77-
78-
// var indices = _indices;
79-
// for (var i = 0; i < indices.Count; i++)
80-
// {
81-
// length += _indices[i].Value.Length + 1;
82-
// }
83-
84-
// length = length == 0 ? 0 : length - 1;
85-
86-
// _output = string.Create(length, indices, (span, state) =>
87-
// {
88-
// var written = 0;
89-
// for (var i = 0; i < indices.Count; i++)
90-
// {
91-
// var value = state[i].Value.AsSpan();
92-
// value.CopyTo(span[written..]);
93-
// written += value.Length;
94-
95-
// if (i != indices.Count - 1)
96-
// span[written++] = ',';
97-
// }
98-
// });
99-
// }
100-
//}
101-
102-
///// <summary>
103-
///// Investigate whether it's "more efficient" to use a one or many design for Indices.
104-
///// This avoids extra allocations in the case of a single item but is not so good for > 1 item.
105-
///// </summary>
106-
//[MemoryDiagnoser]
107-
//public class OneOrMany
108-
//{
109-
// private readonly List<IndexName> _indices = new();
110-
111-
// private Indices? _finalIndices = null;
112-
// private IndicesV2? _finalIndicesV2 = null;
113-
114-
// private readonly ElasticsearchClientSettings _settings = new();
115-
116-
// [Params(1, 3)]
117-
// public int NameCount { get; set; }
118-
119-
// [GlobalSetup]
120-
// public void Setup()
121-
// {
122-
// for (var i = 0; i < NameCount; i++)
123-
// {
124-
// _indices.Add($"item{i}");
125-
// }
126-
// }
127-
128-
// [Benchmark(Baseline = true)]
129-
// public void PureHashSet() => _finalIndices = new Indices(_indices);
130-
131-
// [Benchmark]
132-
// public void OneOrManyConcept()
133-
// {
134-
// if (_indices.Count == 1)
135-
// _finalIndicesV2 = new IndicesV2(_indices[0]);
136-
// else
137-
// _finalIndicesV2 = new IndicesV2(_indices);
138-
// }
139-
140-
// internal partial class IndicesV2
141-
// {
142-
// public static readonly IndicesV2 All = new("_all");
143-
144-
// private readonly HashSet<IndexName>? _indices;
145-
// private readonly IndexName? _index;
146-
147-
// internal IndicesV2(IndexName index) => _index = index;
148-
149-
// public IndicesV2(IEnumerable<IndexName> indices)
150-
// {
151-
// if (_indices is null)
152-
// _indices = new HashSet<IndexName>();
153-
154-
// _indices.UnionWith(indices);
155-
// }
156-
// }
157-
//}

benchmarks/Profiling/Profiling.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@
1414
<ProjectReference Include="..\..\src\Elastic.Clients.Elasticsearch\Elastic.Clients.Elasticsearch.csproj" />
1515
</ItemGroup>
1616

17+
<ItemGroup>
18+
<PackageReference Update="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" />
19+
</ItemGroup>
20+
1721
</Project>

benchmarks/Profiling/Program.cs

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,54 @@
1-
var req1 = new Elastic.Clients.Elasticsearch.IndexManagement.DeleteRequest("test");
1+
using System;
2+
using System.IO;
3+
using System.Linq;
4+
using System.Text;
5+
using Elastic.Clients.Elasticsearch;
6+
using Elastic.Clients.Elasticsearch.Helpers;
7+
using Elastic.Transport;
8+
using JetBrains.Profiler.Api;
9+
10+
//var req1 = new Elastic.Clients.Elasticsearch.IndexManagement.DeleteRequest("test");
211

312
////var list = new List<IndexName>();
413
////IEnumerable<IndexName> items = new IndexName[] { "a", "b" };
514

6-
//MemoryProfiler.ForceGc();
15+
var stream = new MemoryStream(Encoding.UTF8.GetBytes(@"{""status"":""yellow"",""timed_out"":false,""number_of_nodes"":1,""number_of_data_nodes"":1,""active_primary_shards"":6,""active_shards"":6,""relocating_shards"":0,""initializing_shards"":0,""unassigned_shards"":4,""delayed_unassigned_shards"":0,""number_of_pending_tasks"":0,""number_of_in_flight_fetch"":0,""task_max_waiting_in_queue_millis"":0,""active_shards_percent_as_number"":60.0}"));
716

8-
//MemoryProfiler.CollectAllocations(true);
17+
var data = Enumerable.Range(0, 1000).Select(r => new App.SampleData()).ToList();
918

10-
//MemoryProfiler.GetSnapshot();
19+
var alphaClient = new ElasticsearchClient(new ElasticsearchClientSettings(new Uri("https://localhost:9600"))
20+
.Authentication(new BasicAuthentication("elastic", "c236sjjbMP3nUGDxU_Z6"))
21+
.ServerCertificateValidationCallback((a, b, c, d) => true));
22+
23+
//var bulkAll = alphaClient.BulkAll(data, b => b
24+
// .Index("v8")
25+
// .BackOffRetries(2)
26+
// .ContinueAfterDroppedDocuments()
27+
// .Size(100));
28+
29+
//var observer = bulkAll.Wait(TimeSpan.FromMinutes(1), n => { });
30+
31+
_ = await alphaClient.RequestResponseSerializer.DeserializeAsync<Elastic.Clients.Elasticsearch.Cluster.ClusterHealthResponse>(stream);
32+
33+
MemoryProfiler.ForceGc();
34+
35+
MemoryProfiler.CollectAllocations(true);
36+
37+
MemoryProfiler.GetSnapshot();
38+
39+
//bulkAll = alphaClient.BulkAll(data, b => b
40+
// .Index("v8")
41+
// .BackOffRetries(2)
42+
// .ContinueAfterDroppedDocuments()
43+
// .Size(100));
44+
45+
//observer = bulkAll.Wait(TimeSpan.FromMinutes(1), n => { });
46+
47+
var result = await alphaClient.RequestResponseSerializer.DeserializeAsync<Elastic.Clients.Elasticsearch.Cluster.ClusterHealthResponse>(stream);
48+
49+
MemoryProfiler.GetSnapshot();
50+
51+
Console.WriteLine(result.ClusterName.ToString());
1152

1253
////var req = new DeleteRequest("test");
1354

@@ -43,8 +84,18 @@
4384

4485
////MemoryProfiler.GetSnapshot();
4586

46-
////MemoryProfiler.CollectAllocations(false);
87+
MemoryProfiler.CollectAllocations(false);
4788

4889
////// Ensure no GC between snapshots
4990
////_ = indices2.Values.Count;
5091
////_ = indicesList2.Values.Count;
92+
93+
namespace App
94+
{
95+
public class SampleData
96+
{
97+
public SampleData() => Value = Guid.NewGuid();
98+
99+
public Guid Value { get; }
100+
}
101+
}

build/scripts/packages.lock.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@
8080
},
8181
"FSharp.Core": {
8282
"type": "Direct",
83-
"requested": "[6.0.1, )",
84-
"resolved": "6.0.1",
85-
"contentHash": "VrFAiW8dEEekk+0aqlbvMNZzDvYXmgWZwAt68AUBqaWK8RnoEVUNglj66bZzhs4/U63q0EfXlhcEKnH1sTYLjw=="
83+
"requested": "[5.0.0, )",
84+
"resolved": "5.0.0",
85+
"contentHash": "iHoYXA0VaSQUONGENB1aVafjDDZDZpwu39MtaRCTrmwFW/cTcK0b2yKNVYneFHJMc3ChtsSoM9lNtJ1dYXkHfA=="
8686
},
8787
"Microsoft.NETFramework.ReferenceAssemblies": {
8888
"type": "Direct",

0 commit comments

Comments
 (0)