2016-08-05 8 views
2

ジェネリックを使用して、スレッドローカル静的配列を作成したいと思います。配列のサイズは型によって異なります。私は次のようなことをしようとしています:ThreadLocalとgenerics

type LeftoverPool private() = 
    static let instance = new ThreadLocal<'T[]>(fun() -> Array.zeroCreate (Vector<'T>.Count)) 
    static member Instance = instance.Value 

しかし、これはintにTを制約します。 インスタンスメソッドをジェネリック型または型にしようとしましたが、これを動作させることはできません。

+0

あなたは静的に解決されたジェネリックを使用しています。代わりに通常の種類を試してください。ちょうど '^ T'を' 'T'で置き換えてください。 –

+0

私は、通常のジェネリックを使用する例を編集しました。しかしながら、問題は依然として残っている。 – jackmott

+1

ジェネリックパラメータの生成元を指定してください。 'LeftoverPool < 'T>' –

答えて

3

タイプの観点からは、現時点でやっていることは実際には意味をなさない。

の意味を解決できないため、静的プロパティInstanceがありますが、タイプが完全にあいまいです。これを実行するためには、

type LeftoverPool<'T> private() = 
    static let instance = new ThreadLocal<'T[]>(fun() -> Array.zeroCreate<'T> (Vector<'T>.Count)) 
    static member Instance = instance.Value 
+0

ああ、私はこれを試してみましたが、我々は制約エラーを取得し、私はそれらをすべて適用したら、この作品のように見えます。いくつかのテスト後のビットで受け付けます。 'ベクトル<'T>場合 – jackmott

+0

@jackmottはい、' ' 'あなたは' LeftoverPool <'T>にそれらを適用しなければならないT' 'すぎにいくつかの制約があります。 – TheInnerLight

+0

Downvoter:おそらくあなたは、あなたがこの回答についてに反対するかを説明できますか? – TheInnerLight

2

は、その静的なメンバーがタイプに特異的である、ジェネリック型を作成します。:例えば、含む型に型注釈を伝播する必要があります。 Resharper(C#用)は警告を出しますが、ここに本当に必要なものがあります。

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 
---------------------