Reduce CPU time when initiating RepositoryCacheKeys (#18267)
* Avoid an unneeded lookups in the Keys dictionary when initiating key cache * Add further comments and unit tests around updated code. --------- Co-authored-by: Andy Butland <abutland73@gmail.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Umbraco.Cms.Core.Persistence.Repositories;
|
||||
|
||||
/// <summary>
|
||||
@@ -5,15 +7,34 @@ namespace Umbraco.Cms.Core.Persistence.Repositories;
|
||||
/// </summary>
|
||||
public static class RepositoryCacheKeys
|
||||
{
|
||||
// used to cache keys so we don't keep allocating strings
|
||||
/// <summary>
|
||||
/// A cache for the keys we don't keep allocating strings.
|
||||
/// </summary>
|
||||
private static readonly Dictionary<Type, string> Keys = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the repository cache key for the provided type.
|
||||
/// </summary>
|
||||
public static string GetKey<T>()
|
||||
{
|
||||
Type type = typeof(T);
|
||||
return Keys.TryGetValue(type, out var key) ? key : Keys[type] = "uRepo_" + type.Name + "_";
|
||||
|
||||
// The following code is a micro-optimization to avoid an unnecessary lookup in the Keys dictionary, when writing the newly created key.
|
||||
// Previously, the code was:
|
||||
// return Keys.TryGetValue(type, out var key)
|
||||
// ? key
|
||||
// : Keys[type] = "uRepo_" + type.Name + "_";
|
||||
|
||||
// Look up the existing value or get a reference to the newly created default value.
|
||||
ref string? key = ref CollectionsMarshal.GetValueRefOrAddDefault(Keys, type, out _);
|
||||
|
||||
// As we have the reference, we can just assign it if null, without the expensive write back to the dictionary.
|
||||
return key ??= "uRepo_" + type.Name + "_";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the repository cache key for the provided type and Id.
|
||||
/// </summary>
|
||||
public static string GetKey<T, TId>(TId? id)
|
||||
{
|
||||
if (EqualityComparer<TId?>.Default.Equals(id, default))
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Persistence.Repositories;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.PropertyEditors;
|
||||
|
||||
[TestFixture]
|
||||
public class RepositoryCacheKeysTests
|
||||
{
|
||||
[Test]
|
||||
public void GetKey_Returns_Expected_Key_For_Type()
|
||||
{
|
||||
var key = RepositoryCacheKeys.GetKey<IContent>();
|
||||
Assert.AreEqual("uRepo_IContent_", key);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetKey_Returns_Expected_Key_For_Type_And_Id()
|
||||
{
|
||||
var key = RepositoryCacheKeys.GetKey<IContent, int>(1000);
|
||||
Assert.AreEqual("uRepo_IContent_1000", key);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user