Roslyn ObjectPool 结构包装器
Roslyn ObjectPool struct wrapper
我正在查看 Roslyn ObjectPool 实现 (https://github.com/dotnet/roslyn/blob/master/src/Compilers/Core/SharedCollections/ObjectPool%601.cs),但我不明白为什么他们不简单地选择一个 T 数组而是将 T 包装在一个结构中?
[DebuggerDisplay("{Value,nq}")]
private struct Element
{
internal T Value;
}
...
private readonly Element[] _items;
这样做的目的是什么?
这是在设置引用类型的数组项时避免性能问题的常用技巧。数组在 CLR(和 JVM)上是变体。您可以将 string
写入 object[]
。这需要运行时检查您实际上没有将字符串存储到 SomethingElse[]
中。使用该值类型技巧,无需在运行时执行该检查。
我认为这是出于性能原因。 Array of struct 是垃圾收集器的朋友,而不是 Array of class.
来自5 Tips and Techniques for Avoiding Automatic GC Collections
With an array of class instances, the GC has to check each item in
that array to see if it is a live object or not (the same is true for
generic collections, which use an internal array). With an array of
structs, the GC just looks to see if the array itself is still a live
object, since structs cannot be null (this is true even for
Nullable structs, which just use an internal tracking mechanism to
determine nullity). So that is potentially thousands or even millions
of items that the GC does not need to examine when a collection runs!
我正在查看 Roslyn ObjectPool 实现 (https://github.com/dotnet/roslyn/blob/master/src/Compilers/Core/SharedCollections/ObjectPool%601.cs),但我不明白为什么他们不简单地选择一个 T 数组而是将 T 包装在一个结构中?
[DebuggerDisplay("{Value,nq}")]
private struct Element
{
internal T Value;
}
...
private readonly Element[] _items;
这样做的目的是什么?
这是在设置引用类型的数组项时避免性能问题的常用技巧。数组在 CLR(和 JVM)上是变体。您可以将 string
写入 object[]
。这需要运行时检查您实际上没有将字符串存储到 SomethingElse[]
中。使用该值类型技巧,无需在运行时执行该检查。
我认为这是出于性能原因。 Array of struct 是垃圾收集器的朋友,而不是 Array of class.
来自5 Tips and Techniques for Avoiding Automatic GC Collections
With an array of class instances, the GC has to check each item in that array to see if it is a live object or not (the same is true for generic collections, which use an internal array). With an array of structs, the GC just looks to see if the array itself is still a live object, since structs cannot be null (this is true even for Nullable structs, which just use an internal tracking mechanism to determine nullity). So that is potentially thousands or even millions of items that the GC does not need to examine when a collection runs!