我想使用泛型创建一些线程本地静态数组。数组的大小取决于类型。我正在尝试做类似的事情:
type LeftoverPool private () =
static let instance = new ThreadLocal<'T[]>(fun () -> Array.zeroCreate (Vector<'T>.Count))
static member Instance = instance.Value
但是这会将T限制为int。 我已经尝试使实例方法通用或类型,但无法使其工作。
答案 0 :(得分:3)
从类型的角度来看,您目前正在尝试做的事情确实没有意义。
你有一个静态属性Instance
,但它的类型完全不明确,因为它无法解析'T
的含义。为此,您需要将类型注释传播到包含类型,例如:
type LeftoverPool<'T> private () =
static let instance = new ThreadLocal<'T[]>(fun () -> Array.zeroCreate<'T> (Vector<'T>.Count))
static member Instance = instance.Value
答案 1 :(得分:2)
创建泛型类型,然后其静态成员将特定于该类型。 Resharper(用于C#)将发出警告,但这是您真正需要的。
此外,您还需要对ThreadStatic
vs ThreadLocal
进行基准测试,后者实际上是一个对象池,与仅存在于特殊域中的线程静态字段相比,我有一些查找开销每个线程的内存区域。
<强>更新强>
无论如何我打算测试一下,这是代码和输出。 ThreadStatic更快。
[TestFixture]
public class BuffersTests {
public static class LocalBuffers<T> {
[ThreadStatic]
private static T[] _threadStatic;
private static ThreadLocal<T[]> _threadLocal = new ThreadLocal<T[]>(() => new T[10]);
public static T[] ThreadStatic => _threadStatic ?? (_threadStatic = new T[10]);
public static T[] ThreadLocal => _threadLocal.Value;
}
[Test, Ignore]
public void ThreadStaticVsThreadLocal() {
for (int r = 0; r < 10; r++) {
const int count = 100000000;
var sw = new Stopwatch();
sw.Restart();
var sum = 0L;
for (var i = 0; i < count; i++) {
var buffer = LocalBuffers<int>.ThreadStatic;
buffer[0] = 123;
sum += buffer[0] + buffer[1];
}
Assert.IsTrue(sum > 0);
sw.Stop();
Console.WriteLine($"ThreadStatic {sw.ElapsedMilliseconds}");
sw.Restart();
sum = 0L;
for (var i = 0; i < count; i++) {
var buffer = LocalBuffers<int>.ThreadLocal;
buffer[0] = 123;
sum += buffer[0] + buffer[1];
}
Assert.IsTrue(sum > 0);
sw.Stop();
Console.WriteLine($"ThreadLocal {sw.ElapsedMilliseconds}");
Console.WriteLine("---------------------");
}
}
}
ThreadStatic 1286
ThreadLocal 1860
---------------------
ThreadStatic 1312
ThreadLocal 1849
---------------------
ThreadStatic 1334
ThreadLocal 1933
---------------------
ThreadStatic 1390
ThreadLocal 2076
---------------------
ThreadStatic 1438
ThreadLocal 2088
---------------------
ThreadStatic 1295
ThreadLocal 2216
---------------------
ThreadStatic 1317
ThreadLocal 1972
---------------------
ThreadStatic 1380
ThreadLocal 1943
---------------------
ThreadStatic 1410
ThreadLocal 1970
---------------------