Skip to content

Commit

Permalink
Performance gain on primary key lookup
Browse files Browse the repository at this point in the history
Added a static dictionary that "caches" the PK lookup after the first
time.  This way it doesn't have to use reflection to get the PK property
of the entity after the first time.  It is 3 times as fast getting it
from the dictionary than using the Reflection based on my simple
testing.
  • Loading branch information
Jeff Treuting committed Jul 9, 2013
1 parent 7da3069 commit 5c063d6
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 12 deletions.
11 changes: 11 additions & 0 deletions SharpRepository.Repository/Helpers/InternalCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Reflection;

namespace SharpRepository.Repository.Helpers
{
internal static class InternalCache
{
internal static readonly IDictionary<Tuple<Type, Type>, PropertyInfo> PrimaryKeyMapping = new Dictionary<Tuple<Type, Type>, PropertyInfo>();
}
}
25 changes: 13 additions & 12 deletions SharpRepository.Repository/RepositoryBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Linq.Expressions;
using SharpRepository.Repository.Caching;
using SharpRepository.Repository.Helpers;
using SharpRepository.Repository.Queries;
using SharpRepository.Repository.Specifications;
using SharpRepository.Repository.Transactions;
Expand Down Expand Up @@ -538,34 +539,34 @@ protected virtual ISpecification<T> ByPrimaryKeySpecification(TKey key)
return new Specification<T>(lambda);
}

// TODO: cache this call so it's done on the first loading only
protected virtual PropertyInfo GetPrimaryKeyPropertyInfo()
{
// checks for properties in this order that match TKey type
// 1) RepositoryPrimaryKeyAttribute
// 2) Id
// 3) [Type Name]Id
var type = typeof(T);
var pkType = typeof (TKey);
var pkType = typeof(TKey);
var tupleKey = Tuple.Create(type, pkType);

// check the static cache, this means that the reflection is only done the first time this repository type is used
// big performance gain from this - over 3 times faster after first load
if (InternalCache.PrimaryKeyMapping.ContainsKey(tupleKey))
{
return InternalCache.PrimaryKeyMapping[tupleKey];
}

var propertyName = Conventions.GetPrimaryKeyName(type);

if (String.IsNullOrEmpty(propertyName)) return null;

var propInfo = type.GetProperty(propertyName);
propInfo = propInfo == null || propInfo.PropertyType != pkType ? null : propInfo;


return propInfo == null || propInfo.PropertyType != pkType ? null : propInfo;
InternalCache.PrimaryKeyMapping[tupleKey] = propInfo;
return propInfo;
}

// private static PropertyInfo GetPropertyCaseInsensitive(IReflect type, string propertyName, Type propertyType)
// {
// // make the property reflection lookup case insensitive
// const BindingFlags bindingFlags = BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance;
//
// return type.GetProperty(propertyName, bindingFlags, null, propertyType, new Type[0], new ParameterModifier[0]);
// }

public abstract IEnumerator<T> GetEnumerator();
IEnumerator IEnumerable.GetEnumerator()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
<Compile Include="CompoundKeyRepositoryBase.Batch.cs" />
<Compile Include="CompoundKeyRepositoryBase.BatchItem.cs" />
<Compile Include="DisabledCache.cs" />
<Compile Include="Helpers\InternalCache.cs" />
<Compile Include="IDisabledCache.cs" />
<Compile Include="Linq\LinqHelpers.cs" />
<Compile Include="Queries\IPagingOptions.cs" />
Expand Down

0 comments on commit 5c063d6

Please sign in to comment.