Skip to content

Commit 8da262d

Browse files
authored
Feature/2005 large composite disposable perf (#2092)
1 parent 6f283f9 commit 8da262d

File tree

3 files changed

+237
-36
lines changed

3 files changed

+237
-36
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT License.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Reactive.Linq;
7+
8+
using BenchmarkDotNet.Attributes;
9+
10+
namespace Benchmarks.System.Reactive
11+
{
12+
/// <summary>
13+
/// Completion of a wide fan-out/in scenario.
14+
/// </summary>
15+
/// <remarks>
16+
/// <para>
17+
/// This was added to address https://github.com/dotnet/reactive/issues/2005 in which completion
18+
/// takes longer and longer to handle as the number of groups increases.
19+
/// </para>
20+
/// <para>
21+
/// The queries in this benchmark represent the common 'fan out/in' pattern in Rx. It is often
22+
/// useful to split a stream into groups to enable per-group processing, and then to recombine
23+
/// the data back into a single stream. These benchmarks don't do any per-group processing, so
24+
/// they might look pointless, but we're trying to measure the minimum unavoidable overhead
25+
/// that any code using this technique will encounter.
26+
/// </para>
27+
/// </remarks>
28+
[MemoryDiagnoser]
29+
public class GroupByCompletion
30+
{
31+
private IObservable<int> observable;
32+
33+
[Params(200_000, 1_000_000)]
34+
public int NumberOfSamples { get; set; }
35+
36+
[Params(10, 100, 1_000, 10_000, 100_000, 150_000, 200_000)]
37+
public int NumberOfGroups { get; set; }
38+
39+
[GlobalSetup]
40+
public void GlobalSetup()
41+
{
42+
var data = new int[NumberOfSamples];
43+
for (var i = 0; i < data.Length; ++i)
44+
{
45+
data[i] = i;
46+
}
47+
48+
observable = data.ToObservable();
49+
}
50+
51+
[Benchmark]
52+
public void GroupBySelectMany()
53+
{
54+
var numberOfGroups = NumberOfGroups;
55+
56+
observable!.GroupBy(value => value % numberOfGroups)
57+
.SelectMany(groupOfInts => groupOfInts)
58+
.Subscribe(intValue => { });
59+
}
60+
61+
[Benchmark]
62+
public void GroupByMerge()
63+
{
64+
var numberOfGroups = NumberOfGroups;
65+
66+
observable!.GroupBy(value => value % numberOfGroups)
67+
.Merge()
68+
.Subscribe(intValue => { });
69+
}
70+
}
71+
}

Rx.NET/Source/benchmarks/Benchmarks.System.Reactive/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ private static void Main()
2727
typeof(ScalarScheduleBenchmark),
2828
typeof(StableCompositeDisposableBenchmark),
2929
typeof(SubjectBenchmark),
30-
typeof(ComparisonAsyncBenchmark)
30+
typeof(ComparisonAsyncBenchmark),
31+
typeof(GroupByCompletion)
3132
#if (CURRENT)
3233
,typeof(AppendPrependBenchmark)
3334
,typeof(PrependVsStartWtihBenchmark)

0 commit comments

Comments
 (0)