未验证 提交 5717fc28 编写于 作者: S Stephen Toub 提交者: GitHub

Avoid Hashtable-related allocations in DataBindEngine (#6501)

The _valueConverterTable is a Hashtable that uses a struct-based key.  It's boxing every time a lookup is performed or an add is performed.
上级 8853b341
...@@ -368,13 +368,14 @@ internal ViewRecord GetViewRecord(object collection, CollectionViewSource key, T ...@@ -368,13 +368,14 @@ internal ViewRecord GetViewRecord(object collection, CollectionViewSource key, T
Type targetType, Type targetType,
bool targetToSource) bool targetToSource)
{ {
IValueConverter result = _valueConverterTable[sourceType, targetType, targetToSource]; ValueConverterTableKey key = new ValueConverterTableKey(sourceType, targetType, targetToSource);
if (!_valueConverterTable.TryGetValue(key, out IValueConverter result))
if (result == null)
{ {
result = DefaultValueConverter.Create(sourceType, targetType, targetToSource, this); result = DefaultValueConverter.Create(sourceType, targetType, targetToSource, this);
if (result != null) if (result != null)
_valueConverterTable.Add(sourceType, targetType, targetToSource, result); {
_valueConverterTable.Add(key, result);
}
} }
return result; return result;
...@@ -657,63 +658,26 @@ private void OnLayoutUpdated(object sender, EventArgs e) ...@@ -657,63 +658,26 @@ private void OnLayoutUpdated(object sender, EventArgs e)
// //
//------------------------------------------------------ //------------------------------------------------------
// cache of default value converters (so that all uses of string-to-int can private readonly struct ValueConverterTableKey : IEquatable<ValueConverterTableKey>
// share the same converter)
class ValueConverterTable : Hashtable
{ {
struct Key private readonly Type _sourceType, _targetType;
{ private readonly bool _targetToSource;
Type _sourceType, _targetType;
bool _targetToSource;
public Key(Type sourceType, Type targetType, bool targetToSource)
{
_sourceType = sourceType;
_targetType = targetType;
_targetToSource = targetToSource;
}
public override int GetHashCode() public ValueConverterTableKey(Type sourceType, Type targetType, bool targetToSource)
{
return _sourceType.GetHashCode() + _targetType.GetHashCode();
}
public override bool Equals(object o)
{
if (o is Key)
{
return (this == (Key)o);
}
return false;
}
public static bool operator ==(Key k1, Key k2)
{
return k1._sourceType == k2._sourceType &&
k1._targetType == k2._targetType &&
k1._targetToSource == k2._targetToSource;
}
public static bool operator !=(Key k1, Key k2)
{
return !(k1 == k2);
}
}
public IValueConverter this[Type sourceType, Type targetType, bool targetToSource]
{ {
get _sourceType = sourceType;
{ _targetType = targetType;
Key key = new Key(sourceType, targetType, targetToSource); _targetToSource = targetToSource;
object value = base[key];
return (IValueConverter)value;
}
} }
public void Add(Type sourceType, Type targetType, bool targetToSource, IValueConverter value) public override int GetHashCode() => _sourceType.GetHashCode() + _targetType.GetHashCode();
{
base.Add(new Key(sourceType, targetType, targetToSource), value); public override bool Equals(object o) => o is ValueConverterTableKey other && Equals(other);
}
public bool Equals(ValueConverterTableKey other) =>
_sourceType == other._sourceType &&
_targetType == other._targetType &&
_targetToSource == other._targetToSource;
} }
private sealed class DataBindEngineShutDownListener : ShutDownListener private sealed class DataBindEngineShutDownListener : ShutDownListener
...@@ -741,7 +705,7 @@ internal override void OnShutDown(object target, object sender, EventArgs e) ...@@ -741,7 +705,7 @@ internal override void OnShutDown(object target, object sender, EventArgs e)
private UIElement _layoutElement; private UIElement _layoutElement;
private ViewManager _viewManager = new ViewManager(); private ViewManager _viewManager = new ViewManager();
private CommitManager _commitManager = new CommitManager(); private CommitManager _commitManager = new CommitManager();
private ValueConverterTable _valueConverterTable = new ValueConverterTable(); private Dictionary<ValueConverterTableKey, IValueConverter> _valueConverterTable = new Dictionary<ValueConverterTableKey, IValueConverter>();
private PathParser _pathParser = new PathParser(); private PathParser _pathParser = new PathParser();
private IAsyncDataDispatcher _defaultAsyncDataDispatcher; private IAsyncDataDispatcher _defaultAsyncDataDispatcher;
private HybridDictionary _asyncDispatchers; private HybridDictionary _asyncDispatchers;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册