2016-08-05 3 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

정규 generics 사용 예제를 편집했습니다. 그러나 문제는 여전히 남아 있습니다. – 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# 용)는 경고를 표시하지만 실제로 필요한 것은 여기에 있습니다.

또한 ThreadStaticThreadLocal까지 벤치 마크해야합니다. 나중에는 사실 개체 풀이며 각 스레드의 특수 메모리 영역에있는 스레드 정적 필드와 비교할 때 조회 오버 헤드가 있습니다.

업데이트

어쨌든 잠시 동안 테스트려고, 여기에 코드와 출력됩니다. 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 
---------------------