2013-05-09 1 views
0

이 문제를 설명하기 위해 Microsoft Scripting Runtime 참조 및 아래 코드를 사용하여 C# 프로젝트를 컴파일하십시오. 결과 실행 파일의 단일 인스턴스를 실행하십시오. 내 12 코어 머신에서 읽기 루프는 일관되게 약 180ms가 걸립니다. 실행 파일의 다른 인스턴스를 시작하면 추가 실행 파일 당 약 100ms 정도 속도가 느려집니다.Scripting.Dictionary 성능이 여러 프로세스에서 발생합니다.

아이디어가 있습니까? 다른 사전 구현으로 전환하는 것 이외의 다른 솔루션이 있습니까?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication4 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      System.Diagnostics.Stopwatch stp = new System.Diagnostics.Stopwatch(); 
      var dict = (Scripting.IDictionary)(new Scripting.Dictionary()); 
      stp.Start(); 
      for (int i = 1; i < 1000; ++i) 
      { 
       Object s = i.ToString(); 
       dict.Add(ref s, ref s); 
      } 
      Console.WriteLine("After Add {0}", stp.ElapsedMilliseconds); 
      object q = null; 
      for (int j = 0; j < 1000; ++j) 
      { 
       long old = stp.ElapsedMilliseconds; 
       for (int i = 1; i < 10000; ++i) 
       { 
        q = null; 
        object s = i.ToString() as object; 
        q = dict.get_Item(ref s); 
       } 
       long newval = stp.ElapsedMilliseconds; 
       Console.WriteLine("After Retrieve {0}", newval - old); 
      } 

     } 
    } 
} 
+1

타이밍 코드가있는 동안 콘솔을 가로 질러 1000 줄의 텍스트를 스크롤하는 것은 정말 나쁜 생각입니다. –

+2

나는 1997 년에'ScriptingDictionary'를 썼습니다.나는 당신의 문제의 원인이 무엇인지 모르지만, 알아내는 것이 궁금 할 것입니다. 그것이 무엇이든, 나는 결코 고칠 수 없을 것이라고 확신 할 수 있습니다. –

답변

0

에릭, 당신은 문제가 Scripting.Dictionary 특정하지 않습니다 듣고 기뻐할, 오히려 아파트 스레딩 모델 것입니다. 혼합 된 스레딩 모델이 성능에 미치는 영향에 대해서는 MSDN에서 읽을 수 있습니다. 그러나 놀라운 점은 out-of-process에 미치는 영향입니다.

위의 예에서 Scripting.Dictionary 호출을 대체하여 아래에 설명 된 것처럼 단일 메서드로 내 자신의 COM 개체를 만들 수있었습니다. 그런 다음 Test.rgs 파일의 'Apartment'및 'Both'스레딩 모델간에 전환하여 재구성하고 MTA 사용 가능 개체에서 프로세스 간 영향이 해결되었는지 확인합니다.

또한 디버거를 연결하고 프로세스를 일시 중지 한 다음 procexp (Microsoft SysInternals에서)를 사용하면 COM 마샬링을 위해 관리되는 단일 대기열이 있다고 가정하는 커널로 호출 스택 제목을 볼 수 있습니다. 서로 다른 공정에 걸쳐 병목이 발생합니다.

이 저하는 다른 객체에 대한 호출을 마샬링 할 때도 발생합니다.이 호출은 Scripting.Dictionary로 호출하는 응용 프로그램 하나와 DoNothing()을 호출하는 다른 응용 프로그램을 실행하고 느려지는 것을 모두 관찰하여 볼 수 있습니다.

우리는 다른 사전 구현을 사용합니다 (Scripting.Dictionary 스레딩 모델을 변경할 수도 있지만 현명하지 못한 것처럼 보입니다).

COM 마샬링의 프로세스 간 영향에 대해 여전히 뛰어난 질문이 있다고 가정합니다. 다른 사람이 더 좋은 대답을하지 않으면 멀티 프로세스 환경에서 아파트 스레딩을 피하도록 권장해야합니다 ...? 는 C++ ATL 템플릿 (내가 VS 2008를 사용하고 있습니다)를 사용하여

  • Visual Studio에서 새 프로젝트를 만들고 테스트 COM 개체를 만들기

    .

  • 서버 유형 DLL을 선택하십시오.
  • 프로젝트를 마우스 오른쪽 단추로 클릭하고 클래스 추가 ... -> ATL 단순 개체를 클릭합니다.
  • 약식 이름을 지정하십시오. "테스트", 아파트 스레딩이 선택되었는지 확인하십시오.
  • 클래스 뷰에서 인터페이스 (ITest)를 마우스 오른쪽 단추로 클릭하고 메서드 추가 ...
  • 메서드 이름을 지정합니다. "DoNothing"을 선택하고 기본 옵션을 그대로 둡니다.
  • 메소드 구현이 비어 있는지 확인하고 빌드하십시오.

이제 테스트 응용 프로그램에서 COM 참조를 추가하고 DoNothing() 메서드를 호출 할 수 있습니다.

+1

감사합니다. 당신이 그것을 알아 낸 것을 기쁘게 생각합니다. 덧붙여 말하자면, Scripting.Dictionary의 한 릴리즈는 Apartment가 아닌 Both로 잘못 표시되었습니다. 내 실수. 여기서 재미있는 이야기를 읽을 수 있습니다. http://blogs.msdn.com/b/ericlippert/archive/2003/09/19/53054.aspx –

관련 문제