2016-08-05 2 views
2

Я хотел бы создать некоторые потоковые локальные статические массивы, используя generics. Размер массива зависит от типа. Я пытаюсь сделать что-то вроде:ThreadLocal и generics

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

Но это сдерживает T к int. Я пробовал сделать общий метод экземпляра или тип, но не могу заставить это работать.

+0

Вы используете статически разрешенный общий тип, вместо этого попробуйте обычный вид - просто замените '^ T' на' 'T'. –

+0

Я отредактировал пример, чтобы использовать обычные дженерики. Однако проблемы остаются. – jackmott

+1

Попробуйте указать, откуда генерируется общий параметр. 'LeftoverPool < 'T>' –

ответ

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

А, я пробовал это, но мы получаем ошибки ограничения, но как только я применил их все, похоже, что это работает. Принят немного после некоторого тестирования. – jackmott

+0

@jackmott Да, если 'Vector <'T>' имеет некоторые ограничения на '' T', вы должны были бы применить их к 'LeftoverPool <'T>' тоже. – TheInnerLight

+0

Downvoter: возможно, вы могли бы объяснить, что возражаете против этого ответа? – TheInnerLight

2

Создание универсального типа, то его статические члены будут специфичными для данного типа. Resharper (для C#) выдает предупреждение, но вот что вам действительно нужно.

Кроме того, вы должны бенчмарка ThreadStatic против ThreadLocal, а также, позже фактически пула объектов и моим есть подстановки накладных расходов по сравнению с резьбовыми статическими полями, которые просто проживают в специальной области памяти для каждого потока.

Update

Я собирался проверить его на некоторое время, в любом случае, здесь код и выход. 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 
---------------------