Browse Source

Reuse empty value store arrays.

pull/5074/head
Dariusz Komosinski 6 years ago
parent
commit
dc698b3b1d
  1. 24
      src/Avalonia.Base/Utilities/AvaloniaPropertyValueStore.cs
  2. 3
      tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs
  3. 14
      tests/Avalonia.Benchmarks/NullCursorFactory.cs

24
src/Avalonia.Base/Utilities/AvaloniaPropertyValueStore.cs

@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
#nullable enable
namespace Avalonia.Utilities
{
@ -9,12 +12,14 @@ namespace Avalonia.Utilities
/// <typeparam name="TValue">Stored value type.</typeparam>
internal sealed class AvaloniaPropertyValueStore<TValue>
{
// The last item in the list is always int.MaxValue.
private static readonly Entry[] s_emptyEntries = { new Entry { PropertyId = int.MaxValue, Value = default! } };
private Entry[] _entries;
public AvaloniaPropertyValueStore()
{
// The last item in the list is always int.MaxValue
_entries = new[] { new Entry { PropertyId = int.MaxValue, Value = default } };
_entries = s_emptyEntries;
}
private (int, bool) TryFindEntry(int propertyId)
@ -86,7 +91,7 @@ namespace Avalonia.Utilities
return (0, false);
}
public bool TryGetValue(AvaloniaProperty property, out TValue value)
public bool TryGetValue(AvaloniaProperty property, [MaybeNull] out TValue value)
{
(int index, bool found) = TryFindEntry(property.Id);
if (!found)
@ -132,7 +137,18 @@ namespace Avalonia.Utilities
if (found)
{
Entry[] entries = new Entry[_entries.Length - 1];
var newLength = _entries.Length - 1;
// Special case - one element left means that value store is empty so we can just reuse our "empty" array.
if (newLength == 1)
{
_entries = s_emptyEntries;
return;
}
var entries = new Entry[newLength];
int ix = 0;
for (int i = 0; i < _entries.Length; ++i)

3
tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs

@ -17,7 +17,8 @@ namespace Avalonia.Benchmarks.Layout
_app = UnitTestApplication.Start(
TestServices.StyledWindow.With(
renderInterface: new NullRenderingPlatform(),
threadingInterface: new NullThreadingPlatform()));
threadingInterface: new NullThreadingPlatform(),
standardCursorFactory: new NullCursorFactory()));
_root = new TestRoot(true, null)
{

14
tests/Avalonia.Benchmarks/NullCursorFactory.cs

@ -0,0 +1,14 @@
using System;
using Avalonia.Input;
using Avalonia.Platform;
namespace Avalonia.Benchmarks
{
internal class NullCursorFactory : IStandardCursorFactory
{
public IPlatformHandle GetCursor(StandardCursorType cursorType)
{
return new PlatformHandle(IntPtr.Zero, "null");
}
}
}
Loading…
Cancel
Save