committed by
GitHub
3 changed files with 159 additions and 4 deletions
@ -0,0 +1,94 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Avalonia.Utilities |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A list like struct optimized for holding zero or one items.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of items held in the list.</typeparam>
|
||||
|
/// <remarks>
|
||||
|
/// Once more than value has been added to this storage it will switch to using <see cref="List"/> internally.
|
||||
|
/// </remarks>
|
||||
|
public ref struct ValueSingleOrList<T> |
||||
|
{ |
||||
|
private bool _isSingleSet; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Single contained value. Only valid if <see cref="IsSingle"/> is set.
|
||||
|
/// </summary>
|
||||
|
public T Single { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// List of values.
|
||||
|
/// </summary>
|
||||
|
public List<T> List { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// If this struct is backed by a list.
|
||||
|
/// </summary>
|
||||
|
public bool HasList => List != null; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// If this struct contains only single value and storage was not promoted to a list.
|
||||
|
/// </summary>
|
||||
|
public bool IsSingle => List == null && _isSingleSet; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Adds a value.
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">Value to add.</param>
|
||||
|
public void Add(T value) |
||||
|
{ |
||||
|
if (List != null) |
||||
|
{ |
||||
|
List.Add(value); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (!_isSingleSet) |
||||
|
{ |
||||
|
Single = value; |
||||
|
|
||||
|
_isSingleSet = true; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
List = new List<T>(); |
||||
|
|
||||
|
List.Add(Single); |
||||
|
List.Add(value); |
||||
|
|
||||
|
Single = default; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Removes a value.
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">Value to remove.</param>
|
||||
|
public bool Remove(T value) |
||||
|
{ |
||||
|
if (List != null) |
||||
|
{ |
||||
|
return List.Remove(value); |
||||
|
} |
||||
|
|
||||
|
if (!_isSingleSet) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (EqualityComparer<T>.Default.Equals(Single, value)) |
||||
|
{ |
||||
|
Single = default; |
||||
|
|
||||
|
_isSingleSet = false; |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Styling; |
||||
|
using BenchmarkDotNet.Attributes; |
||||
|
|
||||
|
namespace Avalonia.Benchmarks.Styling |
||||
|
{ |
||||
|
[MemoryDiagnoser] |
||||
|
public class SelectorBenchmark |
||||
|
{ |
||||
|
private readonly Control _notMatchingControl; |
||||
|
private readonly Calendar _matchingControl; |
||||
|
private readonly Selector _isCalendarSelector; |
||||
|
private readonly Selector _classSelector; |
||||
|
|
||||
|
public SelectorBenchmark() |
||||
|
{ |
||||
|
_notMatchingControl = new Control(); |
||||
|
_matchingControl = new Calendar(); |
||||
|
|
||||
|
const string className = "selector-class"; |
||||
|
|
||||
|
_matchingControl.Classes.Add(className); |
||||
|
|
||||
|
_isCalendarSelector = Selectors.Is<Calendar>(null); |
||||
|
_classSelector = Selectors.Class(null, className); |
||||
|
} |
||||
|
|
||||
|
[Benchmark] |
||||
|
public SelectorMatch IsSelector_NoMatch() |
||||
|
{ |
||||
|
return _isCalendarSelector.Match(_notMatchingControl); |
||||
|
} |
||||
|
|
||||
|
[Benchmark] |
||||
|
public SelectorMatch IsSelector_Match() |
||||
|
{ |
||||
|
return _isCalendarSelector.Match(_matchingControl); |
||||
|
} |
||||
|
|
||||
|
[Benchmark] |
||||
|
public SelectorMatch ClassSelector_NoMatch() |
||||
|
{ |
||||
|
return _classSelector.Match(_notMatchingControl); |
||||
|
} |
||||
|
|
||||
|
[Benchmark] |
||||
|
public SelectorMatch ClassSelector_Match() |
||||
|
{ |
||||
|
return _classSelector.Match(_matchingControl); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue