// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information.
using System;
using System.Reactive.Linq;
using BenchmarkDotNet.Attributes;
namespace Benchmarks.System.Reactive
{
///
/// Completion of a wide fan-out/in scenario.
///
///
///
/// This was added to address https://github.com/dotnet/reactive/issues/2005 in which completion
/// takes longer and longer to handle as the number of groups increases.
///
///
/// The queries in this benchmark represent the common 'fan out/in' pattern in Rx. It is often
/// useful to split a stream into groups to enable per-group processing, and then to recombine
/// the data back into a single stream. These benchmarks don't do any per-group processing, so
/// they might look pointless, but we're trying to measure the minimum unavoidable overhead
/// that any code using this technique will encounter.
///
///
[MemoryDiagnoser]
public class GroupByCompletion
{
private IObservable observable;
[Params(200_000, 1_000_000)]
public int NumberOfSamples { get; set; }
[Params(10, 100, 1_000, 10_000, 100_000, 150_000, 200_000)]
public int NumberOfGroups { get; set; }
[GlobalSetup]
public void GlobalSetup()
{
var data = new int[NumberOfSamples];
for (var i = 0; i < data.Length; ++i)
{
data[i] = i;
}
observable = data.ToObservable();
}
[Benchmark]
public void GroupBySelectMany()
{
var numberOfGroups = NumberOfGroups;
observable!.GroupBy(value => value % numberOfGroups)
.SelectMany(groupOfInts => groupOfInts)
.Subscribe(intValue => { });
}
[Benchmark]
public void GroupByMerge()
{
var numberOfGroups = NumberOfGroups;
observable!.GroupBy(value => value % numberOfGroups)
.Merge()
.Subscribe(intValue => { });
}
}
}