Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions src/DynamicData.Benchmarks/Cache/Sum_Cache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Reactive.Subjects;

using BenchmarkDotNet.Attributes;

using DynamicData.Aggregation;

namespace DynamicData.Benchmarks.Cache;

[MemoryDiagnoser]
[MarkdownExporterAttribute.GitHub]
public class Sum_Cache
{
private IReadOnlyList<IChangeSet<Item, int>> _addChangeSets = null!;
private IReadOnlyList<IChangeSet<Item, int>> _replaceChangeSets = null!;
private IReadOnlyList<IChangeSet<Item, int>> _removeChangeSets = null!;
private IReadOnlyList<IChangeSet<Item, int>> _refreshChangeSets = null!;

[Params(100, 500, 1_000, 10_000)]
public int Count { get; set; }

[GlobalSetup]
public void Setup()
{
var source = new ChangeAwareCache<Item, int>(capacity: Count);
var items = new Item[Count + 1];

var addChangeSets = new List<IChangeSet<Item, int>>(capacity: Count);
for (var id = 1; id <= Count; ++id)
{
var item = new Item()
{
Id = id,
Value = id
};
items[id] = item;
source.Add(item, key: id);
addChangeSets.Add(source.CaptureChanges());
}
_addChangeSets = addChangeSets;

var replaceChangeSets = new List<IChangeSet<Item, int>>(capacity: Count);
for (var id = 1; id <= Count; ++id)
{
var replacement = new Item()
{
Id = id,
Value = id * 2
};
items[id] = replacement;
source.AddOrUpdate(replacement, key: id);
replaceChangeSets.Add(source.CaptureChanges());
}
_replaceChangeSets = replaceChangeSets;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've generated an invalid sequence of changes for all of these, except for _addChangeSets. source.CaptureChanges() also clears out the changes buffer, so when you get around to sending _replaceChangeSets to your operator, what you've got is nothing but Replace changes that refer to items that never had an Add. Apparently, the existing implementation of .Sum() doesn't care, but your new one might.


var refreshChangeSets = new List<IChangeSet<Item, int>>(capacity: Count);
for (var id = 1; id <= Count; ++id)
{
// Mutate in place, then refresh - the scenario stateless aggregation cannot currently observe.
items[id].Value += 1;
source.Refresh(id);
refreshChangeSets.Add(source.CaptureChanges());
}
_refreshChangeSets = refreshChangeSets;

var removeChangeSets = new List<IChangeSet<Item, int>>(capacity: Count);
for (var id = 1; id <= Count; ++id)
{
source.Remove(id);
removeChangeSets.Add(source.CaptureChanges());
}
_removeChangeSets = removeChangeSets;
}

[Benchmark]
public void Adds() => Run(_addChangeSets);

[Benchmark]
public void Replaces() => Run(_replaceChangeSets);

[Benchmark]
public void Refreshes() => Run(_refreshChangeSets);

[Benchmark]
public void Removes() => Run(_removeChangeSets);

private static void Run(IReadOnlyList<IChangeSet<Item, int>> changeSets)
{
using var source = new Subject<IChangeSet<Item, int>>();

using var subscription = source
.Sum(static item => item.Value)
.Subscribe();

foreach (var changeSet in changeSets)
source.OnNext(changeSet);

source.OnCompleted();
}

private sealed class Item
{
public required int Id { get; init; }

public int Value { get; set; }
}
}
103 changes: 103 additions & 0 deletions src/DynamicData.Benchmarks/List/Sum_List.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Reactive.Subjects;

using BenchmarkDotNet.Attributes;

using DynamicData.Aggregation;

namespace DynamicData.Benchmarks.List;

[MemoryDiagnoser]
[MarkdownExporterAttribute.GitHub]
public class Sum_List
{
private IReadOnlyList<IChangeSet<Item>> _addChangeSets = null!;
private IReadOnlyList<IChangeSet<Item>> _replaceChangeSets = null!;
private IReadOnlyList<IChangeSet<Item>> _removeChangeSets = null!;
private IReadOnlyList<IChangeSet<Item>> _refreshChangeSets = null!;

[Params(100, 500, 1_000, 10_000)]
public int Count { get; set; }

[GlobalSetup]
public void Setup()
{
var source = new ChangeAwareList<Item>(capacity: Count);

var addChangeSets = new List<IChangeSet<Item>>(capacity: Count);
for (var id = 1; id <= Count; ++id)
{
source.Add(new Item()
{
Id = id,
Value = id
});
addChangeSets.Add(source.CaptureChanges());
}
_addChangeSets = addChangeSets;

var replaceChangeSets = new List<IChangeSet<Item>>(capacity: Count);
for (var index = 0; index < Count; ++index)
{
source[index] = new Item()
{
Id = index + 1,
Value = (index + 1) * 2
};
replaceChangeSets.Add(source.CaptureChanges());
}
_replaceChangeSets = replaceChangeSets;

var refreshChangeSets = new List<IChangeSet<Item>>(capacity: Count);
for (var index = 0; index < Count; ++index)
{
// Mutate in place, then refresh - the scenario stateless aggregation cannot currently observe.
source[index].Value += 1;
source.RefreshAt(index);
refreshChangeSets.Add(source.CaptureChanges());
}
_refreshChangeSets = refreshChangeSets;

var removeChangeSets = new List<IChangeSet<Item>>(capacity: Count);
for (var id = 1; id <= Count; ++id)
{
source.RemoveAt(source.Count - 1);
removeChangeSets.Add(source.CaptureChanges());
}
_removeChangeSets = removeChangeSets;
}

[Benchmark]
public void Adds() => Run(_addChangeSets);

[Benchmark]
public void Replaces() => Run(_replaceChangeSets);

[Benchmark]
public void Refreshes() => Run(_refreshChangeSets);

[Benchmark]
public void Removes() => Run(_removeChangeSets);

private static void Run(IReadOnlyList<IChangeSet<Item>> changeSets)
{
using var source = new Subject<IChangeSet<Item>>();

using var subscription = source
.Sum(static item => item.Value)
.Subscribe();

foreach (var changeSet in changeSets)
source.OnNext(changeSet);

source.OnCompleted();
}

private sealed class Item
{
public required int Id { get; init; }

public int Value { get; set; }
}
}
Loading