Skip to content

Commit

Permalink
perf: get rid of a couple closures (#103)
Browse files Browse the repository at this point in the history
* perf: get rid of a couple closures

* replace variable abbreviation with proper name

Co-authored-by: Glenn <[email protected]>
  • Loading branch information
cabauman and glennawatson authored Dec 13, 2020
1 parent 610bf06 commit 599391a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 21 deletions.
24 changes: 11 additions & 13 deletions src/ReactiveMarbles.PropertyChanged/GetMemberFuncCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,23 @@ namespace ReactiveMarbles.PropertyChanged
internal static class GetMemberFuncCache<TFrom, TReturn>
{
#if !UIKIT
private static readonly
ConcurrentDictionary<(Type FromType, string MemberName), Func<TFrom, TReturn>> Cache
= new ConcurrentDictionary<(Type, string), Func<TFrom, TReturn>>();
private static readonly ConcurrentDictionary<MemberInfo, Func<TFrom, TReturn>> Cache = new(new MemberFuncCacheKeyComparer());
#endif

public static Func<TFrom, TReturn> GetCache(MemberInfo memberInfo)
{
#if UIKIT
switch (memberInfo)
{
case PropertyInfo propertyInfo:
return input => (TReturn)propertyInfo.GetValue(input);
case FieldInfo fieldInfo:
return input => (TReturn)fieldInfo.GetValue(input);
default:
throw new ArgumentException($"Cannot handle member {memberInfo.Name}", nameof(memberInfo));
}
switch (memberInfo)
{
case PropertyInfo propertyInfo:
return input => (TReturn)propertyInfo.GetValue(input);
case FieldInfo fieldInfo:
return input => (TReturn)fieldInfo.GetValue(input);
default:
throw new ArgumentException($"Cannot handle member {memberInfo.Name}", nameof(memberInfo));
}
#else
return Cache.GetOrAdd((memberInfo.DeclaringType, memberInfo.Name), _ =>
return Cache.GetOrAdd(memberInfo, static memberInfo =>
{
var instance = Expression.Parameter(typeof(TFrom), "instance");
Expand Down
22 changes: 22 additions & 0 deletions src/ReactiveMarbles.PropertyChanged/MemberFuncCacheKeyComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2019-2020 ReactiveUI Association Incorporated. All rights reserved.
// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System.Collections.Generic;
using System.Reflection;

namespace ReactiveMarbles.PropertyChanged
{
internal sealed class MemberFuncCacheKeyComparer : IEqualityComparer<MemberInfo>
{
public bool Equals(MemberInfo x, MemberInfo y)
{
return (x.DeclaringType, x.Name) == (y.DeclaringType, y.Name);
}

public int GetHashCode(MemberInfo obj)
{
return (obj.DeclaringType, obj.Name).GetHashCode();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,17 @@ public static IObservable<TReturn> WhenPropertyValueChanges<TObj, TReturn>(

if (i == expressionChain.Count - 1)
{
var function = GetMemberFuncCache<INotifyPropertyChanged, TReturn>.GetCache(memberInfo);
return currentObservable
.Where(parent => parent.Value != null)
.Select(parent => GenerateObservable(parent.Value, memberInfo, function))
return Observable.Return(memberInfo)
.CombineLatest(currentObservable, (memberInfo, parent) => (memberInfo, sender: parent.Sender, value: parent.Value))
.Where(x => x.value != null)
.Select(x => GenerateObservable(x.value, x.memberInfo, GetMemberFuncCache<INotifyPropertyChanged, TReturn>.GetCache(x.memberInfo)))
.Switch();
}

var iFunction = GetMemberFuncCache<INotifyPropertyChanged, INotifyPropertyChanged>.GetCache(memberInfo);
currentObservable = currentObservable
.Where(parent => parent.Value != null)
.Select(parent => GenerateObservable(parent.Value, memberInfo, iFunction))
currentObservable = Observable.Return(memberInfo)
.CombineLatest(currentObservable, (memberInfo, parent) => (memberInfo, sender: parent.Sender, value: parent.Value))
.Where(x => x.value != null)
.Select(x => GenerateObservable(x.value, x.memberInfo, GetMemberFuncCache<INotifyPropertyChanged, INotifyPropertyChanged>.GetCache(x.memberInfo)))
.Switch();

i++;
Expand Down

0 comments on commit 599391a

Please sign in to comment.