Jak kosztowne is.NET odbicie?

Ciągle słyszę, jak źle jest używać odbicia. Chociaż generalnie unikam refleksji i rzadko znajduję sytuacje, w których bez niej nie da się rozwiązać mojego problemu, zastanawiałem się...

Dla tych, którzy używali odbicia w aplikacjach, mierzyliście hity wydajności i czy naprawdę jest tak źle?

Author: Peter Mortensen, 2008-08-25

13 answers

Jest. Ale to zależy od tego, co próbujesz zrobić.

Używam reflection do dynamicznego ładowania zestawów (wtyczek) i jego wydajność "kara" nie jest problemem, ponieważ operacja jest czymś, co robię podczas uruchamiania aplikacji.

Jednak, jeśli odbijasz się w serii zagnieżdżonych pętli z wywołaniami reflection na każdej z nich, powiedziałbym, że powinieneś wrócić do swojego kodu:)

W przypadku operacji "kilka razy", odbicie jest całkowicie dopuszczalne i nie zauważysz wszelkie opóźnienia lub problemy z nim. Jest to bardzo potężny mechanizm i jest nawet używany przez. Net, więc nie rozumiem, dlaczego nie powinieneś spróbować.

 118
Author: Martin Marconcini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-24 23:48:33

Jeff Richter w swoim przemówieniu The Performance of Everyday Things pokazuje, że wywołanie metody przez refleksję jest około 1000 razy wolniejsze niż wywołanie jej normalnie.

Wskazówka Jeffa: jeśli chcesz wywołać metodę wiele razy, użyj reflection one, aby ją znaleźć, a następnie przypisz ją do delegata, a następnie wywołaj delegata.

 140
Author: ESRogs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-02 00:24:10

Wydajność odbicia zależy od implementacji (powtarzające się wywołania powinny być buforowane np: entity.GetType().GetProperty("PropName")). Ponieważ większość odbicia, które widzę na co dzień, jest używana do wypełniania jednostek z czytników danych lub innych struktur typu repozytorium, postanowiłem porównać wydajność konkretnie na odbiciu, gdy jest używana do uzyskania lub ustawienia właściwości obiektów.

Wymyśliłem test, który moim zdaniem jest sprawiedliwy, ponieważ buforuje wszystkie powtarzające się wywołania i tylko razy rzeczywistą wartość SetValue lub GetValue call. 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żalnych ulepszeń 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 dobrze wykonana.

Wykres czasu (y) względem liczby encji (x)

Powyższy wykres pokazuje wynik mojego małego benchmarka i pokazuje, że mechanizmy, które przewyższają odbicie, robią to zauważalnie dopiero po znaku 100 000 cykli. Większość DALs tylko zwrócić kilkaset lub może tysiące wierszy na raz i na tych poziomach odbicie wykonuje dobrze.

 54
Author: grenade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-09 15:09:24

Jeśli nie jesteś w pętli, nie martw się o to.

 13
Author: David Plumpton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-02 01:09:39

Moim najbardziej istotnym doświadczeniem było pisanie kodu do porównywania dowolnych dwóch jednostek danych tego samego typu w dużym modelu obiektowym. Działa, próbował, biegł jak pies, oczywiście.

Byłem przygnębiony, potem z dnia na dzień zdałem sobie sprawę, że bez zmiany logiki, mogę użyć tego samego algorytmu do automatycznego generowania metod wykonywania porównania, ale statycznie dostęp do właściwości. Dostosowanie kodu do tego celu nie zajęło dużo czasu i miałem możliwość zrobienia głębokiego porównanie właściwości obiektów z kodem statycznym, które można aktualizować po kliknięciu przycisku przy każdej zmianie modelu obiektowego.

Chodzi mi o to, że w rozmowach z kolegami, ponieważ kilka razy wskazywałem, że ich użycie reflection może polegać na autogeneracji kodu do kompilacji, a nie na wykonywaniu operacji runtime i często jest to warte rozważenia.

 12
Author: Gaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-31 12:18:42

Nie masowo. Nigdy nie miałem z tym problemu w rozwoju 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 o jego wydajność w rozwoju pulpitu.

W Compact Framework (w którym zazwyczaj jestem), jest to dość dużo anathema i należy go unikać jak zarazy w większości przypadków. Nadal mogę uciec z używaniem go rzadko, ale muszę być bardzo ostrożny z jego aplikacja, która jest o wiele mniej zabawna. :(

 12
Author: Quibblesome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-08 16:59:39

Jest wystarczająco źle, że musisz się martwić nawet o refleksję wykonywaną wewnętrznie przez biblioteki. NET dla kodu krytycznego dla wydajności.

Poniższy przykład jest przestarzały-prawda w czasie (2008), ale dawno temu naprawiony w nowszych wersjach CLR. Odbicie w ogóle jest jednak trochę kosztowne!

Przypadek: nigdy nie powinieneś używać elementu zadeklarowanego jako "obiekt" w lock (C#) / SyncLock (VB.NET) w kodzie wysokowydajnym. Dlaczego? Ponieważ CLR nie może zablokować typu wartości, co oznacza, że musi sprawdzić typ odbicia w czasie wykonywania, aby sprawdzić, czy obiekt jest rzeczywiście typem wartości zamiast typu odniesienia.

 9
Author: McKenzieG1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-05 16:39:25

Podobnie jak w przypadku wszystkich rzeczy w programowaniu, musisz zrównoważyć koszty wydajności z jakąkolwiek uzyskaną korzyścią. Refleksja jest nieocenionym narzędziem, gdy jest używana z ostrożnością. Stworzyłem bibliotekę mapowania O / R W C#, która używała reflection do tworzenia wiązań. To działało fantastycznie dobrze. Większość kodu odbicia została wykonana tylko raz, więc każdy hit wydajności był dość mały, ale korzyści były duże. Gdybym pisał nowy algorytm sortowania fandangled, prawdopodobnie nie używałbym reflection, ponieważ to prawdopodobnie źle skalowałaby się.

Doceniam, że nie odpowiedziałam na twoje pytanie. Chodzi mi o to, że to nie ma znaczenia. W stosownych przypadkach użyj odbicia. To po prostu kolejna funkcja językowa, której musisz nauczyć się, jak i kiedy używać.

 5
Author: Mike Thompson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-25 00:04:13

Odbicie może mieć zauważalny wpływ na wydajność, jeśli używasz 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 odbiciu. 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ś montaż, polecam Mono.Cecil , który jest bardzo lekki i szybki

 3
Author: aku,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-25 00:01:54

Odbicie jest kosztowne ze względu na wiele kontroli, które musi wykonać runtime za każdym razem, gdy wystąpisz o metodę, która pasuje do listy parametrów. Gdzieś głęboko w środku istnieje kod, który zapętla wszystkie metody dla typu, weryfikuje jego widoczność, sprawdza typ powrotu, a także sprawdza typ każdego parametru. To wszystko kosztuje czas.

Kiedy wykonujesz tę metodę wewnętrznie jest jakiś kod, który robi takie rzeczy jak sprawdzanie, czy przekazałeś zgodną listę parametry przed wykonaniem rzeczywistej metody docelowej.

Jeśli to możliwe, zawsze zaleca się buforowanie obsługi metody, jeśli w przyszłości będzie się ją stale używać. Podobnie jak wszystkie dobre Porady programistyczne, często ma sens unikanie powtarzania się. W takim przypadku byłoby marnotrawstwem ciągłe wyszukiwanie metody z określonymi parametrami, a następnie wykonywanie jej za każdym razem.

Rozejrzyj się po źródle i zobacz, co się robi.

 3
Author: mP.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-25 05:41:49

Jak ze wszystkim, chodzi o ocenę sytuacji. W DotNetNuke Istnieje dość podstawowy komponent o nazwie FillObject, który używa odbicia do wypełniania obiektów z danych.

Jest to dość powszechny scenariusz i jest artykuł o MSDN, używanie Reflection do wiązania obiektów biznesowych z ASP.NET Kontrola formularzy to dotyczy kwestii wydajności.

Pomijając wydajność, jedną rzeczą, której nie lubię w używaniu refleksji w tym konkretnym scenariuszu, jest że ma tendencję do zmniejszania zdolności do zrozumienia kodu na szybki rzut oka, co dla mnie nie wydaje się warte wysiłku, jeśli uważasz, że również tracisz bezpieczeństwo kompilacji w przeciwieństwie do mocno wpisanych zestawów danych lub czegoś w rodzaju LINQ do SQL .

 3
Author: lomaxx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-22 09:51:56

Odbicie nie spowalnia drastycznie wydajności aplikacji. Możesz być w stanie zrobić pewne rzeczy szybciej, nie używając reflection, ale jeśli Reflection jest najprostszym sposobem na osiągnięcie pewnej funkcjonalności, użyj go. Zawsze możesz refakturować kod z dala od odbicia, jeśli stanie się to problemem perf.

 2
Author: Chris Pietschmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-15 22:03:15

Myślę, że okaże się, że odpowiedź jest, to zależy. To nic wielkiego, jeśli chcesz umieścić go w aplikacji listy zadań. Jest to wielka sprawa, jeśli chcesz umieścić go w bibliotece Facebook persistence.

 1
Author: Travis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-22 10:01:01