提交 20f05577 编写于 作者: C CyrusNajmabadi

Make our reference maps less overhead.

上级 2d2fed79
......@@ -2,10 +2,8 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
......@@ -39,9 +37,11 @@ internal sealed partial class ObjectReader : IDisposable
/// <summary>
/// Map of reference id's to deserialized objects.
///
/// These are not readonly because they're structs and we mutate htemthem.
/// </summary>
private readonly ReaderReferenceMap<object> _objectReferenceMap;
private readonly ReaderReferenceMap<string> _stringReferenceMap;
private ReaderReferenceMap<object> _objectReferenceMap;
private ReaderReferenceMap<string> _stringReferenceMap;
/// <summary>
/// Copy of the global binder data that maps from Types to the appropriate reading-function
......@@ -67,8 +67,8 @@ internal sealed partial class ObjectReader : IDisposable
Debug.Assert(BitConverter.IsLittleEndian);
_reader = new BinaryReader(stream, Encoding.UTF8);
_objectReferenceMap = new ReaderReferenceMap<object>();
_stringReferenceMap = new ReaderReferenceMap<string>();
_objectReferenceMap = ReaderReferenceMap<object>.Create();
_stringReferenceMap = ReaderReferenceMap<string>.Create();
// Capture a copy of the current static binder state. That way we don't have to
// access any locks while we're doing our processing.
......@@ -227,17 +227,18 @@ private object ReadValueWorker()
/// <summary>
/// An reference-id to object map, that can share base data efficiently.
/// </summary>
private class ReaderReferenceMap<T> where T : class
private struct ReaderReferenceMap<T> where T : class
{
private readonly List<T> _values;
internal static readonly ObjectPool<List<T>> s_objectListPool
= new ObjectPool<List<T>>(() => new List<T>(20));
public ReaderReferenceMap()
{
_values = s_objectListPool.Allocate();
}
private ReaderReferenceMap(List<T> values)
=> _values = values;
public static ReaderReferenceMap<T> Create()
=> new ReaderReferenceMap<T>(s_objectListPool.Allocate());
public void Dispose()
{
......@@ -245,21 +246,11 @@ public void Dispose()
s_objectListPool.Free(_values);
}
public int GetNextReferenceId()
{
_values.Add(null);
return _values.Count - 1;
}
public void SetValue(int referenceId, T value)
{
_values[referenceId] = value;
}
public void AddValue(T value)
=> _values.Add(value);
public T GetValue(int referenceId)
{
return _values[referenceId];
}
=> _values[referenceId];
}
internal uint ReadCompressedUInt()
......@@ -321,7 +312,6 @@ private string ReadStringValue(EncodingKind kind)
private unsafe string ReadStringLiteral(EncodingKind kind)
{
int id = _stringReferenceMap.GetNextReferenceId();
string value;
if (kind == EncodingKind.StringUtf8)
{
......@@ -338,7 +328,7 @@ private unsafe string ReadStringLiteral(EncodingKind kind)
}
}
_stringReferenceMap.SetValue(id, value);
_stringReferenceMap.AddValue(value);
return value;
}
......@@ -578,13 +568,11 @@ private Type ReadTypeAfterTag()
private object ReadObject()
{
var id = _objectReferenceMap.GetNextReferenceId();
var typeReader = _binderSnapshot.GetTypeReaderFromId(this.ReadInt32());
// recursive: read and construct instance immediately from member elements encoding next in the stream
var instance = typeReader(this);
_objectReferenceMap.SetValue(id, instance);
_objectReferenceMap.AddValue(instance);
return instance;
}
......
......@@ -32,9 +32,11 @@ internal sealed partial class ObjectWriter : IDisposable
/// Map of serialized object's reference ids. The object-reference-map uses reference equality
/// for performance. While the string-reference-map uses value-equality for greater cache hits
/// and reuse.
///
/// These are not readonly because they're structs and we mutate htemthem.
/// </summary>
private readonly WriterReferenceMap _objectReferenceMap;
private readonly WriterReferenceMap _stringReferenceMap;
private WriterReferenceMap _objectReferenceMap;
private WriterReferenceMap _stringReferenceMap;
/// <summary>
/// Copy of the global binder data that maps from Types to the appropriate reading-function
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册