2008-10-22 3 views
64

가능한 중복 :
How costly is .NET reflection?.NET 리플렉션의 "비용"은 무엇입니까?

나는 반사 나의 가장 친한 친구라고 프로그래밍 정신 현재입니다. 엄격한 인터페이스가 아닌 "느슨한 구현"과 많은 사용자 정의 속성을 허용하는 동적로드 로딩에 많이 사용됩니다.

리플렉션 사용에 대한 "실제"비용은 얼마입니까?

테이블 정의에 대한 모든 속성의 LINQ 이전 DAL 개체 코드와 같이 자주 반영되는 유형의 캐시 리플렉션이 효과적입니까?

캐싱 메모리 사용량이 리플렉션 CPU 사용량을 초과합니까?

+20

3 개월 전의 주제에 대해 어떻게 투표를 했습니까? –

+0

우리는 일반적인 기본 클래스와 리플렉션을 사용하여 데이터 액세스 레이어를 자동화했습니다. 우리의 일반적인 기본 클래스의 대부분은 리플렉션을 사용하여 구현됩니다. 이로 인해 반복적 인 작업을 위해 작성해야하는 코드 줄 수가 크게 줄어 들었습니다. 그러나 성과가 있었다. 어떤 해결책을 채택 했습니까? –

+0

우리는 매우 유사한 접근법을 사용했으며 메타 데이터를 캐싱하고 있습니다. –

답변

53

리플렉션은 많은 양의 유형 메타 데이터가로드되어 처리되어야합니다. 이로 인해 더 큰 메모리 오버 헤드와 느린 실행이 발생할 수 있습니다. this article에 따르면 속성 수정은 약 2.5x-3x 느리고 메서드 호출은 3.5x-4x 느립니다.

여기는 우수한 반사율을 만드는 방법과 오버 헤드가있는 곳을 요약 한 우수한 MSDN article입니다. 나는 당신이 더 많은 것을 배우고 싶다면 독서를 적극 권장합니다.

리플렉션을 통해 코드에 추가 할 수있는 복잡성 요소가있어 코드를 훨씬 혼란스럽고 복잡하게 만들 수 있습니다. Scott Hanselman과 같은 일부 사람들은 리플렉션을 사용하여 해결할 문제보다 더 많은 문제를 만들 것이라고 생각합니다. 팀이 대부분 주니어 개발자 인 경우 특히 그렇습니다.

동적 동작이 많이 필요할 경우 DLR (Dynamic Language Runtime)을 살펴 보는 것이 좋습니다. .NET 4.0에 새로운 변경 사항이 추가되면 일부를 솔루션에 통합 할 수 있는지 확인할 수 있습니다. VB 및 C#의 동적 지원 기능이 추가되어 동적 코드를 매우 우아하게 사용하고 자신 만의 동적 객체를 상당히 직선적으로 만들 수 있습니다.

행운을 빈다.

편집 : Scott의 사이트를 좀 더 파고 들었는데이 내용은 리플렉션에서 podcast입니다. 나는 그것에 귀를 기울이지 않았지만 그것이 가치가있을 수 있습니다.

+0

http://www.hanselman.com/에 대한 링크는 리플렉션에 관한 기사로 이동하지 않습니다. – user1069816

+0

@ user1069816, 스콧의 리플렉션 비용에 대한 특정 기사를 찾지 못했습니다. 그는 Podcast에서 몇 번이나 언급했으며, [Hanselminutes 27 - Reflection] (http://www.hanselminutes.com/27/reflection)의 주제로 깊이 들어갔다. – smaclell

2

위대한 힘은 큰 책임입니다.

반사는 비용과 관련이 있으며, 반사 정도에 따라 응용 프로그램의 속도가 크게 느려질 수 있습니다.

응용 프로그램의 크기에 따라 IoC (Inversion of Control)를 사용하기 때문에 매우 유용 할 수 있습니다.

+0

피터의 삼촌에 대한 +1 스파이더 맨에서 –

1

특히 Jr Devs의 훌륭한 링크와 훌륭한 의견을 보내 주셔서 감사합니다. 오히려 DAL의 일부 큰 impelementations보다

[TableName("Table")] 
public class SomeDal : BaseDal 
{ 
    [FieldName("Field")] 
    public string Field 
} 

을 : 우리의 주니어 개발자가이 작업을 수행하는

은 우리가 쉽다.이는 고위 개발자가 꺼내기 위해 내부 작업을 모두 숨기면서 DAL 개체의 구축 속도를 높입니다.

LINQ가 너무 나 빠졌던 것은 나빴으며, 때때로 우리는 그 중 절반을 썼습니다.

+0

분명히 NHibernate ALT.NET 사람에 따르면 꽤 좋다, 그래서 당신이 대안을보고 가치가있을 수도 있습니다. 내가 참여한 마지막 팀에는 리플렉션을 많이 사용하는 사용자 지정 ORM 레이어가있었습니다. 오직 한 사람 만이 그것을 이해할 수있었습니다. – smaclell

+0

우리의 최종 솔루션은이 레이어를 충분히 잘 감싸서 나중에 프로젝트에 시간이 있으면 레이어를 제거 할 수있게하는 것이 었습니다. 행운을 빈다. 나는 너의 고통을 느낀다. – smaclell

15

리플렉션 속도를 높이기 위해 할 수있는 일이 많이 있습니다. 예를 들어 많은 속성 액세스를 수행하는 경우 HyperDescriptor이 유용 할 수 있습니다.

메서드 호출을 많이 수행하는 경우 Delegate.CreateDelegate을 사용하여 형식화 된 대리자에 메서드를 캐시 할 수 있습니다. 그러면 형식 검사 등을 한 번만 수행합니다 (CreateDelegate).

많은 개체 구성을 수행하는 경우 Delegate.CreateDelegate은 도움이되지 않습니다 (생성자에서는 사용할 수 없습니다). 그러나 (3.5에서) Expression을 사용하여 다시 입력 된 개체로 컴파일 할 수 있습니다 대리자.

그래서 예 : 반사가 느리지 만 지나치게 고통없이 최적화 할 수 있습니다.

+2

얼마나 많은 사람들이 Delegate.CreateDelegate에 대해 몰라서 놀랍습니다. 실제로는 최고의 MSDN 문서를 보유하고 있습니다! – leppie

+1

'CreateDelegate'에 대한 MSDN 링크 http://msdn.microsoft.com/en-us/library/system.delegate.createdelegate.aspx – Dennis

0

리플렉션을 사용할 때 때로는 당신을 물들 일 수있는 한 가지는 리팩토링을 할 때 리플렉션을 사용하여 호출을 업데이트하지 않는 것입니다. resharper와 같은 도구는 메서드 이름을 변경할 때 주석과 문자열을 업데이트하라는 메시지를 표시하므로 대부분 그렇게 할 수 있지만 동적으로 생성 된 메서드를 호출하거나 메서드 이름이 동적으로 생성 된 경우 뭔가를 놓친다.

유일한 해결책은 문서화 및 철저한 단위 테스트입니다.

관련 문제