2010-01-07 2 views
0

내 코드에서 COM 인터페이스를 통해 레거시 Delphi 개체를 인스턴스화합니다. 이 클래스는 여러 번 인스턴스화해야하므로 인스턴스화의 오버 헤드를 줄이기 위해 모든 호출의 70 %가 공통 결과 객체를 갖는 지점에서 캐시합니다.ref. 대신 값으로 캐시하는 .NET COM 래퍼 추가

그러나 캐시 된 후에 개체를 변경하면 변경 내용이 캐시에도 유지됩니다. 이것은 COM 래퍼 인스턴스가 값 대신 참조로 전달되었다고 생각하게합니다.
캐시의 객체가 ref가 아닌 값으로 전달되는지 어떻게 확인할 수 있습니까?

+0

"개체"를 변경한다고 쓰면 Delphi COM 개체 또는 RCW .NET 측 랩핑 프록시를 참조합니까? 물론 COM 객체는 항상 참조로 전달되므로 캐시하면 상태에 대한 변경 사항을 공유해야합니다 ... 아마도 간단한 예가 귀하의 질문을 명확하게 해줍니다. –

+0

이후의 변경은 프록시 클래스에서 수행됩니다. 예제를 추가하겠습니다.하지만 기존의 오브젝트를 사용하는 코드는 평소와 같이 지저분합니다. –

답변

0

나는 그것이 가능하다면 명시 적으로 개체의 복사본을 복제 한 다음 복사본을 캐시해야한다고 생각합니다. 예를 들어 MemberwiseClone 방법을 참조하십시오. 다른 설명은 Cloning objects in C#입니다.

+0

그게 내가 두려워했던 것입니다 : S –

+0

MemberwiseClone이 COM 객체에서 의도 한대로 작동하는지조차 모르겠습니다. ** 기껏해야 ** 공개 속성을 복제 할 수 있지만 메서드를 통해 변형 된 내부 상태는 없습니다. – peterchen

+0

네, 최선을 다하면 포장지를 복제 할 것이고 실제 포장 된 COM 객체를 복제하지 않을 것이라고 생각합니다. – ChrisW

0

먼저 필요한가?

"모든 성능 문제를 해결하는 방법"을지지하는 사람은 아니지만, 귀하는해야합니다.

COM 개체를 인스턴스화하는 오버 헤드는 매우 낮습니다. 즉, 15 년 전의 컴퓨터에서 많은 작은 개체를 사용할 수 있도록 설계되었습니다. 나는 .NET 오버 헤드가 훨씬 더 많지 않다고 가정한다. 그래서 질문은 객체 자체의 초기화이다.

당신이 꽉 루프에서 1,000 개체를 인스턴스화 것을 쉽게 확인할 수 있습니다

COM 개체를
가 참조 본질적이다 (첫 번째 통화를 던져, 그것은 매우 비쌀 수와 평균을 망칠 것) 기본 인터페이스는 인스턴스에 대한 참조 카운트 된 포인터이고 COM은 일반적인 "복제"메서드를 노출하지 않으므로 COM 개체에 대해서는 "값으로 전달"하지 않습니다.

가능한 솔루션 : 기록 중 복사 인스턴스화 정말 비용, 그리고 통화의 대부분이 기본 인스턴스를 통해 수행 할 수 있습니다 경우에만
을, 당신은 기록 중 복사 방식을 구현할 수 있습니다 .

당신은 기본 인스턴스에 대한 참조를 유지하는 래퍼 클래스를 작성해야하고, 개인 인스턴스에 대한 참조는 0으로 초기화

만큼 민간 인스턴스가 null의에 앞으로 모든 게터 기능을 그대로 기본 인스턴스, otherwis, 그들은 개인 인스턴스로 전달합니다.

모든 setter/mutator 호출은 개인 인스턴스로 전달하여 존재하지 않을 때 생성합니다.

이렇게하면 개인 인스턴스의 생성이 첫 번째 변경 전화로 지연됩니다. 그러나이 구성 요소에 대해 관심있는 모든 모든 인터페이스를 래핑해야합니다.

+0

"조숙 한 최적화는 악마입니다"라는 귀하의 알림에 감사드립니다. 나는 측정의 원리를 알고 있습니다. 필자의 경우 비용이 많이 드는 인스턴스화가 아니라 초기화 (DB 값을 개체에 삽입하고 개체 내부의 논리를 트리거하는) 방법이 있습니다. 이 초기화는 요청 당 여러 번 수행되며 사이트 당 분당 수천 회의 요청이 이루어집니다. 성능 분석 (개미)이 지적했듯이 현재 (캐싱과 함께) 전체 앱의 병목 현상이 있습니다. 귀하의 최종 제안을 구현할 것을 고려할 것입니다. –

+0

또한 응용 프로그램의 기존 논리로 인해 캐싱을 제외하고 반복되는 초기화를 피하기 위해 응용 프로그램의 설계를 검토 할 수 없습니다. –

+0

Boris, 저는 이것을 합법적 인 투자 이유로 봅니다 - DB에 액세스하는 "실패 지점"만 제거하는 경우에도 투자해야합니다. – peterchen