未验证 提交 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
Type targetType,
bool targetToSource)
{
IValueConverter result = _valueConverterTable[sourceType, targetType, targetToSource];
if (result == null)
ValueConverterTableKey key = new ValueConverterTableKey(sourceType, targetType, targetToSource);
if (!_valueConverterTable.TryGetValue(key, out IValueConverter result))
{
result = DefaultValueConverter.Create(sourceType, targetType, targetToSource, this);
if (result != null)
_valueConverterTable.Add(sourceType, targetType, targetToSource, result);
{
_valueConverterTable.Add(key, result);
}
}
return result;
......@@ -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
// share the same converter)
class ValueConverterTable : Hashtable
private readonly struct ValueConverterTableKey : IEquatable<ValueConverterTableKey>
{
struct Key
{
Type _sourceType, _targetType;
bool _targetToSource;
public Key(Type sourceType, Type targetType, bool targetToSource)
{
_sourceType = sourceType;
_targetType = targetType;
_targetToSource = targetToSource;
}
private readonly Type _sourceType, _targetType;
private readonly bool _targetToSource;
public override int GetHashCode()
{
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]
public ValueConverterTableKey(Type sourceType, Type targetType, bool targetToSource)
{
get
{
Key key = new Key(sourceType, targetType, targetToSource);
object value = base[key];
return (IValueConverter)value;
}
_sourceType = sourceType;
_targetType = targetType;
_targetToSource = targetToSource;
}
public void Add(Type sourceType, Type targetType, bool targetToSource, IValueConverter value)
{
base.Add(new Key(sourceType, targetType, targetToSource), value);
}
public override int GetHashCode() => _sourceType.GetHashCode() + _targetType.GetHashCode();
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
......@@ -741,7 +705,7 @@ internal override void OnShutDown(object target, object sender, EventArgs e)
private UIElement _layoutElement;
private ViewManager _viewManager = new ViewManager();
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 IAsyncDataDispatcher _defaultAsyncDataDispatcher;
private HybridDictionary _asyncDispatchers;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册