development

.NET 리플렉션 비용이 얼마나 듭니까?

big-blog 2020. 5. 6. 21:54
반응형

.NET 리플렉션 비용이 얼마나 듭니까?


나는 반사가 얼마나 나쁜지를 끊임없이 듣는다. 나는 일반적으로 성찰을 피하고 문제가 없으면 내 문제를 해결할 수없는 상황을 거의 찾지 않지만 궁금합니다 ...

응용 프로그램에서 리플렉션을 사용한 사용자의 경우 성능 적중을 측정 한 적이 있습니까?


그것은. 그러나 그것은 당신이하려는 일에 달려 있습니다.

리플렉션을 사용하여 어셈블리 (플러그인)를 동적으로로드하고 성능 "불이익"은 문제가되지 않습니다. 작업은 응용 프로그램 시작 중에 수행하는 작업이기 때문입니다.

그러나 각각에 대해 리플렉션 호출을 사용하여 일련의 중첩 루프 내부에 반영하는 경우 코드를 다시 방문해야한다고 말하고 싶습니다. :)

"몇 시간"작업의 경우 리플렉션을 완벽하게 수용 할 수 있으며 지연이나 문제가 발생하지 않습니다. 매우 강력한 메커니즘이며 .NET에서도 사용되므로 시도하지 말아야 할 이유를 모르겠습니다.


Jeff Richter는 자신의 강연 에서 일상적인 것들의 성능 (Performance of Everyday Things) 에서 반성으로 메소드를 호출하는 것이 정상적으로 호출하는 것보다 1000 배 느리다 는 것을 보여줍니다 .

Jeff의 팁 : 메소드를 여러 번 호출해야하는 경우 리플렉션을 한 번 사용하여 찾은 다음 델리게이트에 할당 한 다음 델리게이트 를 호출하십시오.


리플렉션 성능은 구현에 따라 다릅니다 (예 : 반복 호출을 캐시해야 함 entity.GetType().GetProperty("PropName")). 매일 보는 대부분의 리플렉션은 데이터 리더 또는 다른 리포지토리 유형 구조에서 엔터티를 채우는 데 사용되므로 객체 속성을 가져 오거나 설정하는 데 사용될 때 리플렉션에 대한 성능을 구체적으로 벤치 마크하기로 결정했습니다.

나는 모든 반복 호출을 캐시하고 실제 SetValue 또는 GetValue 호출 만 곱하기 때문에 공정하다고 생각되는 테스트를 고안했습니다. 성능 테스트를위한 모든 소스 코드는 https://bitbucket.org/grenade/accessortest 에서 bitbucket에 있습니다 . 면밀히 검토하고 격려하십시오.

내가 얻은 결론은 반사 구현이 잘 수행 될 때 한 번에 100,000 행 미만을 반환하는 데이터 액세스 계층에서 반사를 제거하기 위해 실용적이지 않고 눈에 띄는 성능 개선을 제공하지 않는다는 것입니다.

채워진 엔터티 수에 대한 시간 (y) 그래프 (x)

위의 그래프는 제 작은 벤치 마크의 결과를 보여 주며 반사를 능가하는 메커니즘은 100,000 사이클 마크 후에 만 ​​눈에 띄게 나타납니다. 대부분의 DAL은 한 번에 수백 또는 수천 개의 행만 반환하며 이러한 수준에서는 반사가 잘 수행됩니다.


루프가 아닌 경우 걱정하지 마십시오.


저의 가장 적절한 경험은 큰 객체 모델에서 동일한 유형의 두 데이터 엔터티를 속성별로 비교하는 코드를 작성하는 것이 었습니다. 제대로 작동하고 시도해 보았지만 개처럼 달렸습니다.

나는 낙담했고 밤새 논리를 바꾸지 않으면 서 동일한 알고리즘을 사용하여 비교를 수행하지만 속성에 정적으로 액세스하는 메소드를 자동 생성 할 수 있다는 것을 깨달았다. 이 목적을 위해 코드를 수정하는 데 시간이 전혀 걸리지 않았으며 객체 모델이 변경 될 때마다 버튼을 클릭하면 업데이트 될 수있는 정적 코드로 엔티티를 속성별로 비교할 수있는 능력이있었습니다.

내 요점 : 동료들과의 대화에서 여러 번 반영한 이후로 리플렉션을 사용하면 런타임 작업을 수행하는 대신 컴파일하기 위해 코드를 자동 생성하는 것이 가능하며 종종 고려할 가치가 있다고 지적했습니다.


대규모가 아닙니다. Martin이 말한 것처럼 바보 같은 위치에서 사용하지 않는 한 데스크톱 개발에서 문제가 발생하지 않았습니다. 많은 사람들이 데스크톱 개발에서의 성능에 대해 전혀 비이성적 인 두려움을 가지고 있다고 들었습니다.

에서 Compact Framework에서 (나는 보통에있어)하지만, 그것은 거의의 저주 대부분의 경우 전염병처럼 피해야한다. 나는 그것을 자주 사용하지 않고 도망 칠 수는 있지만 재미가 덜한 응용 프로그램에는 실제로주의해야합니다. :(


성능에 중요한 코드를 위해 .NET 라이브러리에서 내부적으로 수행 한 리플렉션에 대해서도 걱정해야 할 정도로 나쁩니다.

다음 예제는 더 이상 사용되지 않습니다 (2008 년). 그러나 최근에는 최신 CLR 버전에서 수정되었습니다. 일반적으로 반사는 여전히 다소 비용이 많이 드는 것입니다!

적절한 예 : 고성능 코드의 lock (C #) / SyncLock (VB.NET) 문에서 "Object"로 선언 된 멤버를 사용해서는 안됩니다. 왜? CLR은 값 형식을 잠글 수 없으므로 런타임 리플렉션 형식 검사를 수행하여 Object가 실제로 참조 형식이 아닌 값 형식인지 확인해야합니다.


As with all things in programming you have to balance performance cost with with any benefit gained. Reflection is an invaluable tool when used with care. I created a O/R mapping library in C# which used reflection to do the bindings. This worked fantastically well. Most of the reflection code was only executed once, so any performance hit was quite small, but the benefits were great. If I were writing a new fandangled sorting algorithm, I would probably not use reflection, since it would probably scale poorly.

I appreciate that I haven't exactly answered your question here. My point is that it doesn't really matter. Use reflection where appropriate. It's just another language feature that you need to learn how and when to use.


Reflection can have noticeable impact on performance if you use it for frequent object creation. I've developed application based on Composite UI Application Block which is relying on reflection heavily. There was a noticeable performance degradation related with objects creation via reflection.

However in most cases there are no problems with reflection usage. If your only need is to inspect some assembly I would recommend Mono.Cecil which is very lightweight and fast


Reflection is costly because of the many checks the runtime must make whenever you make a request for a method that matches a list of parameters. Somewhere deep inside, code exists that loops over all methods for a type, verifies its visibility, checks the return type and also checks the type of each and every parameter. All of this stuff costs time.

When you execute that method internally theres some code that does stuff like checking you passed a compatible list of parameters before executing the actual target method.

If possible it is always recommended that one caches the method handle if one is going to continually reuse it in the future. Like all good programming tips, it often makes sense to avoid repeating oneself. In this case it would be wasteful to continually lookup the method with certain parameters and then execute it each and everytime.

Poke around the source and take a look at whats being done.


As with everything, it's all about assessing the situation. In DotNetNuke there's a fairly core component called FillObject that uses reflection to populate objects from datarows.

This is a fairly common scenario and there's an article on MSDN, Using Reflection to Bind Business Objects to ASP.NET Form Controls that covers the performance issues.

Performance aside, one thing I don't like about using reflection in that particular scenario is that it tends to reduce the ability to understand the code at a quick glance which for me doesn't seem worth the effort when you consider you also lose compile time safety as opposed to strongly typed datasets or something like LINQ to SQL.


Reflection does not drastically slow the performance of your app. You may be able to do certain things quicker by not using reflection, but if Reflection is the easiest way to achieve some functionality, then use it. You can always refactor you code away from Reflection if it becomes a perf problem.


나는 당신이 그 답이 달려 있다는 것을 알게 될 것이라고 생각합니다. 작업 목록 응용 프로그램에 넣고 싶다면 큰 문제가 아닙니다. Facebook의 퍼시스턴스 라이브러리에 넣으려면 큰 문제입니다.

참고 URL : https://stackoverflow.com/questions/25458/how-costly-is-net-reflection

반응형