提交 ed496edb 编写于 作者: C CyrusNajmabadi

Use immutable arrays to lower overhead even more.

上级 b6817ba2
......@@ -2,7 +2,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Collections.Immutable;
namespace Roslyn.Utilities
{
......@@ -20,9 +20,12 @@ internal static class ObjectBinder
private static int s_version;
private static readonly ObjectBinderState s_state = ObjectBinderState.Create(s_version);
private static readonly Stack<ObjectBinderState> s_pool = new Stack<ObjectBinderState>();
private static readonly Dictionary<Type, int> s_typeToIndex = new Dictionary<Type, int>();
private static readonly List<Type> s_types = new List<Type>();
private static readonly List<Func<ObjectReader, object>> s_typeReaders = new List<Func<ObjectReader, object>>();
public static ObjectBinderState AllocateStateCopy()
{
lock (s_gate)
......@@ -34,8 +37,8 @@ public static ObjectBinderState AllocateStateCopy()
}
// Otherwise, create copy from our current state and return that.
var state = ObjectBinderState.Create(s_version);
state.CopyFrom(s_state);
var state = new ObjectBinderState(
s_version, s_typeToIndex, s_types.ToImmutableArray(), s_typeReaders.ToImmutableArray());
return state;
}
......@@ -61,14 +64,22 @@ public static void RegisterTypeReader(Type type, Func<ObjectReader, object> type
{
lock (s_gate)
{
if (s_state.RegisterTypeReader(type, typeReader))
if (s_typeToIndex.ContainsKey(type))
{
// Registering this type mutated state, clear any cached copies we have
// of ourselves. Also increment the version number so that we don't attempt
// to cache any in-flight copies that are returned.
s_version++;
s_pool.Clear();
// We already knew about this type, nothing to register.
return;
}
int index = s_typeReaders.Count;
s_types.Add(type);
s_typeReaders.Add(typeReader);
s_typeToIndex.Add(type, index);
// Registering this type mutated state, clear any cached copies we have
// of ourselves. Also increment the version number so that we don't attempt
// to cache any in-flight copies that are returned.
s_version++;
s_pool.Clear();
}
}
}
......
......@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
......@@ -11,14 +12,14 @@ internal struct ObjectBinderState
{
public readonly int Version;
private readonly Dictionary<Type, int> _typeToIndex;
private readonly List<Type> _types;
private readonly List<Func<ObjectReader, object>> _typeReaders;
private ImmutableArray<Type> _types;
private ImmutableArray<Func<ObjectReader, object>> _typeReaders;
private ObjectBinderState(
public ObjectBinderState(
int version,
Dictionary<Type, int> typeToIndex,
List<Type> types,
List<Func<ObjectReader, object>> typeReaders)
ImmutableArray<Type> types,
ImmutableArray<Func<ObjectReader, object>> typeReaders)
{
Version = version;
_typeToIndex = typeToIndex;
......@@ -26,26 +27,23 @@ internal struct ObjectBinderState
_typeReaders = typeReaders;
}
public static ObjectBinderState Create(int version)
=> new ObjectBinderState(version, new Dictionary<Type, int>(), new List<Type>(), new List<Func<ObjectReader, object>>());
//public void CopyFrom(ObjectBinderState other)
//{
// if (_types.Count == 0)
// {
// Debug.Assert(_typeToIndex.Count == 0);
// Debug.Assert(_types.Count == 0);
// Debug.Assert(_typeReaders.Count == 0);
public void CopyFrom(ObjectBinderState other)
{
if (_types.Count == 0)
{
Debug.Assert(_typeToIndex.Count == 0);
Debug.Assert(_types.Count == 0);
Debug.Assert(_typeReaders.Count == 0);
foreach (var kvp in other._typeToIndex)
{
_typeToIndex.Add(kvp.Key, kvp.Value);
}
// foreach (var kvp in other._typeToIndex)
// {
// _typeToIndex.Add(kvp.Key, kvp.Value);
// }
_types.AddRange(other._types);
_typeReaders.AddRange(other._typeReaders);
}
}
// _types.AddRange(other._types);
// _typeReaders.AddRange(other._typeReaders);
// }
//}
public int GetTypeId(Type type)
=> _typeToIndex[type];
......@@ -76,9 +74,9 @@ public bool RegisterTypeReader(Type type, Func<ObjectReader, object> typeReader)
return false;
}
int index = _typeReaders.Count;
_types.Add(type);
_typeReaders.Add(typeReader);
var index = _typeReaders.Length;
_types = _types.Add(type);
_typeReaders = _typeReaders.Add(typeReader);
_typeToIndex.Add(type, index);
// We may be a local copy of the object-binder-state. Inform the primary
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册