Ciągle słyszę, jak używać złego odbicia. Chociaż generalnie unikam refleksji i rzadko znajduję sytuacje, w których nie można rozwiązać mojego problemu bez niego, zastanawiałem się ...
Czy dla tych, którzy używali refleksji w aplikacjach, zmierzyliście wyniki wydajności i czy naprawdę jest tak źle?
c#
.net
performance
reflection
Dan Herbert
źródło
źródło
Odpowiedzi:
To jest. Ale to zależy od tego, co próbujesz zrobić.
Używam refleksji do dynamicznego ładowania zestawów (wtyczek), a „kara” wydajności nie stanowi problemu, ponieważ operacja jest czymś, co robię podczas uruchamiania aplikacji.
Jeśli jednak odbijasz się w szeregu zagnieżdżonych pętli z wywołaniami odbicia dla każdego, powiedziałbym, że powinieneś ponownie odwiedzić swój kod :)
W przypadku operacji „kilka razy” odbicie jest całkowicie akceptowalne i nie zauważysz żadnych opóźnień ani problemów. Jest to bardzo silny mechanizm i jest nawet używany przez .NET, więc nie rozumiem, dlaczego nie powinieneś spróbować.
źródło
W swoim wystąpieniu The Performance of Everyday Things Jeff Richter pokazuje, że nazywanie metody metodą refleksji jest około 1000 razy wolniejsze niż normalne.
Wskazówka Jeffa: jeśli musisz wywołać tę metodę wiele razy, użyj refleksji, aby ją znaleźć, następnie przypisz ją do delegata , a następnie wywołaj delegata.
źródło
Wydajność odbicia będzie zależeć od implementacji (powtarzalne wywołania powinny być buforowane np .:)
entity.GetType().GetProperty("PropName")
. Ponieważ większość odbić, które widzę na co dzień, jest wykorzystywana do zapełniania jednostek czytnikami danych lub innymi strukturami typu repozytorium, postanowiłem przeprowadzić analizę porównawczą wydajności szczególnie w przypadku odbicia, gdy jest używana do uzyskania lub ustawienia właściwości obiektu.Opracowałem test, który moim zdaniem jest sprawiedliwy, ponieważ buforuje wszystkie powtarzające się połączenia i tylko razy rzeczywiste wywołanie SetValue lub GetValue. Cały kod źródłowy testu wydajności znajduje się w bitbucket pod adresem : https://bitbucket.org/grenade/accessortest . Kontrola jest mile widziana i zachęcana.
Doszedłem do wniosku, że nie jest to praktyczne i nie zapewnia zauważalnej poprawy wydajności w celu usunięcia odbicia w warstwie dostępu do danych, która zwraca mniej niż 100 000 wierszy w czasie, gdy implementacja odbicia jest wykonana poprawnie.
Powyższy wykres pokazuje wyniki mojego małego testu porównawczego i pokazuje, że mechanizmy, które przewyższają odbicie, robią to zauważalnie dopiero po 100 000 cykli. Większość DAL zwraca tylko kilkaset, a może tysiące wierszy jednocześnie, a na tych poziomach odbicie działa dobrze.
źródło
Jeśli nie jesteś w pętli, nie martw się o to.
źródło
Moim najbardziej stosownym doświadczeniem było pisanie kodu do porównywania dowolnych dwóch jednostek danych tego samego typu w dużym modelu obiektowym pod względem właściwości. Sprawdziło się, wypróbowało, oczywiście biegło jak pies.
Byłem przygnębiony, a potem zorientowałem się, że bez zmiany logiki mogę użyć tego samego algorytmu do automatycznego generowania metod przeprowadzania porównania, ale statycznego dostępu do właściwości. Dostosowanie kodu do tego celu nie zajęło mi wcale czasu, a ja miałem możliwość dokładnego porównania właściwości encji ze statycznym kodem, który można aktualizować jednym kliknięciem przy każdej zmianie modelu obiektu.
Chodzi mi o to: w rozmowach ze współpracownikami, ponieważ kilkakrotnie zwracałem uwagę, że ich odbiciem może być automatyczne generowanie kodu w celu kompilacji, a nie wykonywanie operacji w czasie wykonywania, i często warto to rozważyć.
źródło
Nie masowo. Nigdy nie miałem z tym problemu przy tworzeniu pulpitu, chyba że, jak twierdzi Martin, używasz go w głupiej lokalizacji. Słyszałem, że wiele osób ma całkowicie irracjonalne obawy dotyczące jego wydajności w programowaniu komputerów stacjonarnych.
Jednak w Compact Framework (w którym zwykle jestem) jest to raczej anatema i w większości przypadków należy jej unikać jak zarazy. Nadal nie mogę z niego korzystać rzadko, ale muszę bardzo uważać na jego stosowanie, które jest znacznie mniej zabawne. :(
źródło
Wystarczająco źle, że musisz się martwić nawet o refleksję wewnętrznie wykonywaną przez biblioteki .NET w celu uzyskania kodu o krytycznym znaczeniu.
Poniższy przykład jest przestarzały - wówczas prawdziwy (2008), ale dawno temu naprawiony w nowszych wersjach CLR. Jednak refleksja jest nadal dość kosztowna!
Przykład: nigdy nie należy używać elementu zadeklarowanego jako „Object” w instrukcji lock (C #) / SyncLock (VB.NET) w kodzie o wysokiej wydajności. Czemu? Ponieważ CLR nie może zablokować typu wartości, co oznacza, że musi wykonać sprawdzenie typu odbicia w czasie wykonywania, aby sprawdzić, czy obiekt jest w rzeczywistości typem wartości, a nie typem odniesienia.
źródło
Podobnie jak w przypadku wszystkich innych elementów programowania, należy zrównoważyć koszty wydajności z uzyskanymi korzyściami. Odbicie jest nieocenionym narzędziem, gdy jest używane ostrożnie. Utworzyłem bibliotekę mapowania O / R w C #, która używała refleksji do tworzenia powiązań. Działa to fantastycznie dobrze. Większość kodu refleksyjnego została wykonana tylko raz, więc każde uderzenie wydajności było dość małe, ale korzyści były świetne. Gdybym pisał nowy algorytm sortowania wymuszonego, prawdopodobnie nie użyłbym refleksji, ponieważ prawdopodobnie skalowałby się słabo.
Doceniam to, że nie odpowiedziałem tutaj dokładnie na twoje pytanie. Chodzi mi o to, że to naprawdę nie ma znaczenia. W razie potrzeby użyj odbicia. To po prostu kolejna funkcja językowa, której musisz nauczyć się, jak i kiedy używać.
źródło
Odbicie może mieć zauważalny wpływ na wydajność, jeśli użyjesz go do częstego tworzenia obiektów. Opracowałem aplikację opartą na Composite UI Application Block, która w dużym stopniu opiera się na refleksji. Zauważalna była degradacja wydajności związana z tworzeniem obiektów poprzez odbicie.
Jednak w większości przypadków nie ma problemów z użyciem odbicia. Jeśli potrzebujesz tylko sprawdzić jakiś zestaw, polecam Mono.Cecil, który jest bardzo lekki i szybki
źródło
Refleksja jest kosztowna ze względu na wiele kontroli, które środowisko wykonawcze musi wykonać za każdym razem, gdy wysyłasz zapytanie o metodę pasującą do listy parametrów. Gdzieś głęboko w środku istnieje kod, który zapętla wszystkie metody dla danego typu, weryfikuje jego widoczność, sprawdza typ zwracany, a także sprawdza typ każdego parametru. Wszystko to kosztuje czas.
Kiedy wykonujesz tę metodę wewnętrznie, pojawia się kod, który wykonuje takie czynności, jak sprawdzanie, że przekazałeś kompatybilną listę parametrów przed wykonaniem rzeczywistej metody docelowej.
Jeśli to możliwe, zawsze zaleca się buforowanie uchwytu metody, jeśli zamierza się go stale używać w przyszłości. Podobnie jak wszystkie dobre wskazówki dotyczące programowania, często warto unikać powtarzania się. W takim przypadku niepotrzebne byłoby ciągłe wyszukiwanie metody z określonymi parametrami, a następnie wykonywanie jej za każdym razem.
Przeszukuj źródło i spójrz na to, co się dzieje.
źródło
Jak w przypadku wszystkiego, wszystko polega na ocenie sytuacji. W DotNetNuke dostępny jest dość podstawowy komponent,
FillObject
który wykorzystuje odbicie do wypełniania obiektów z baz danych.Jest to dość powszechny scenariusz i jest artykuł na temat MSDN, Użycie refleksji do powiązania obiektów biznesowych z kontrolkami formularzy ASP.NET które obejmuje problemy z wydajnością.
Pomijając wydajność, jedną rzeczą, której nie lubię w odbiciu w tym konkretnym scenariuszu, jest to, że ma tendencję do zmniejszania zdolności do zrozumienia kodu na pierwszy rzut oka, co dla mnie nie wydaje się warte wysiłku, jeśli uważasz, że tracisz także kompilację bezpieczeństwo czasu w przeciwieństwie do silnie typowanych zestawów danych lub czegoś takiego jak LINQ to SQL .
źródło
Odbicie nie powoduje drastycznego spowolnienia działania aplikacji. Możesz być w stanie zrobić pewne rzeczy szybciej, nie używając odbicia, ale jeśli Odbicie jest najprostszym sposobem na osiągnięcie niektórych funkcji, użyj go. Zawsze możesz refaktoryzować kod od Reflection, jeśli stanie się to problemem.
źródło
Myślę, że przekonasz się, że odpowiedź jest zależna. Nie jest to wielka sprawa, jeśli chcesz umieścić go w aplikacji listy zadań. To wielka sprawa, jeśli chcesz umieścić ją w bibliotece trwałości Facebooka.
źródło