2008-11-20 8 views
16

Czy korzystanie z delegatów spowalnia moje programy?Czy korzystanie z delegatów spowalnia moje programy .NET?

Unikałem ich, ponieważ nie mam pojęcia, czy moje programy działają wolniej. Wiem, jeśli powoduję wyjątek (catch), który zużywa dość dużo mocy procesora, ale nie wiem o Delegatach i Zdarzeniach i co robi dla nich .NET.

+0

dlaczego nie przyjąłeś odpowiedzi nawet na to pytanie? – nawfal

Odpowiedz

16

Delegaci są bardzo, bardzo szybcy. Nie tak szybkie, jak bezpośrednie wywołania metod, ale nie tak daleko. Szanse na to, że staną się wąskim gardłem, są znikome.

(Podobnie wyjątki, kiedy jest stosowany prawidłowo, rarely actually cause a performance issue).

Byłoby użyciu delegatów uczynić Twój kod prostsze, bardziej czytelne i bardziej wytrzymałe? Jeśli tak, użyj ich. Zmierz dokładnie swoją wydajność i miej na nią oko. Odejście od czytelności ze względu na wydajność tylko wtedy, gdy dane są jasne.

Jestem pewna, że ​​istnieje kilka wykresów pokazujących szybkość delegatów w porównaniu do interfejsów innych niż wirtualne metody itp. - Nie wiem, gdzie one są, ale zawsze możesz uruchomić testy samodzielnie, jeśli naprawdę się martwisz .

+3

Jon - Właśnie wystrzeliłem reflektor i przyjrzałem się domyślnej implementacji MulticastDelegate.CombineImpl i byłem nieco przerażony, że metoda jest długa i widzę, że odtwarza ona tablice insternally. Myślałam, że delegaci zostaną połączeni za pomocą list powiązanych. Czy wykonałeś jakieś testy, aby sprawdzić, jak naprawdę są one wydajne? – Mark

+2

@ Mark: Nie do łączenia i usuwania, ale rzadko zdarza się to, co zdarza się bardzo często w moim doświadczeniu. Zwykle ci sami delegaci są nazywane wiele, wiele razy (np. Dla LINQ), więc ważniejsza jest prędkość wywołania. –

9

Tylko mały dodatek do postu Jona: gdy jest używany w normalny sposób C# (np. Przez lambdas/anonimowe metody/programy obsługi zdarzeń/itp.), To zdecydowanie są one bardzo szybkie - ale zauważ, że inne ważne użycie delegatów może być do wykonywania kodu dynamicznego (metody zbudowane w środowisku wykonawczym lub istniejące metody poprzez odbicie i Delegate.CreateDelegate). Kiedy jest używany w ten drugi sposób, delegaci oferują bardzo znaczącą poprawę prędkości: ulepszenie (w porównaniu do odbicia Invoke itp.).

Nie zawahaj się więc korzystać z delegatów. A w szczególności, jeśli masz wątpliwości - zmień go na realistyczny kod: nie ma znaczenia, czy potrzeba 1, czy 100 mikro-łasek *, jeśli nadal stanowi to tylko 0,01% całkowitego czasu wykonania.

* = tylko niektóre dowolnie mała ilość czasu ...

+3

Odtąd, myślę, że dam wyniki wydajności w pico-fortnights. Nikt nie może twierdzić, że brakuje informacji, ale uwypukla * względną * naturę większości porównań wydajności. Czas na metodę przedłużenia na TimeSpanie ... –

+1

Czy pico-dwa tygodnie są dłuższe lub krótsze niż mikro-łasica? Dociekliwe umysły chcą wiedzieć :) –

+0

Hah, pico-fortnight! Miły Jon :) –

6

Wydajność może być drażliwy temat, jeśli chodzi o programowanie. Na przykład niektórzy ludzie są absolutnie nieugięci, że boks jest źródłem wszelkiego zła. Inni ludzie sądzą, że konkrety w łańcuchach są hitami o dużej wydajności.

W rzeczywistości wszystko jest względne i wszystko sprowadza się do kontekstu, o którym mówisz. Jeśli programujesz na urządzeniu mobilnym, będziesz chciał zoptymalizować więcej niż w przypadku pracy na komputerze.

Zwykle sprowadza się do kompromisu między wydajnością a elegancją kodu. Powiedzmy, że stworzyłeś cudownie elegancką, łatwą w utrzymaniu i zrozumiałą bazę kodów na świecie. Gdy tylko wprowadzimy pewne optymalizacje wydajności, zaczynamy zamazywać kod za pomocą jakiegoś potencjalnie sprzecznego z intuicją, bardzo specjalistycznego sprzętu. Gdybyśmy poszli do miasta na optymalizację, moglibyśmy zaoszczędzić na wydajności, powiedzmy 5 lub 10 procent, ale w tym procesie zniszczyć elegancję kodu.

Pytanie brzmi "czy warto?".

Jeśli wydajność jest absolutnie kluczowa dla projektu, uruchom profiler na swoim kodzie. Jeśli okaże się, że 90% czasu procesora jest spożywane przez szczególnie nieefektywną metodę, to ta metoda jest dobrym kandydatem do optymalizacji. Zazwyczaj nie warto ścigać się z niską wydajnością, chyba że pracujesz nad aplikacją o krytycznym działaniu.

6

Pracuję na Windows CE, więc tego typu rzeczy są czasami trochę bardziej istotne.Na przykład zuchwała aplikacja odbicia może naprawdę boleć, więc staramy się unikać odbicia, gdzie rozsądne (oczywiście małe zastosowania odbicia są w porządku). Oczywiście nie robię takiego szaleństwa na komputerze.

Słyszałem, jak ludzie mruczą o delegatach i występach w CE, ale jeśli chodzi o mnie, to o to chodzi. Słyszałem, że "spowalnia to wywołanie metody o 30%", ale jeśli to 30% z nieudolnego algorytmu, czyja to wina? Kolejne spowolnienie w CE to metody wirtualne, ponieważ nie ma tabeli odnośników, która ręcznie wykonuje je po raz pierwszy i zapisuje wynik w pamięci podręcznej. Oznacza to, że jeśli odkurzysz całą swoją pamięć, pamięć podręczna zostanie wyczyszczona, a następnym razem otrzyma perfekcję. Ale to rozważyć, czy należy wyrzucić przydatne umiejętności OOP dla dobra wydajności?

Uważam, że wiele z tych "OMG nie używa, że ​​jest zbyt wolny" to tylko wymówki. Głównie wymówki, ponieważ ludzie nie wiedzą, co naprawdę jest nie tak z ich aplikacją i łatwo zrzucić winę na wewnętrzną pracę CLR zamiast własnego kodu. Jeśli Twój wynik jest do dupy, to sądzę, że przez 99,9% czasu możesz zmienić coś w swojej części aplikacji lub projektu, który nie wyrzuca narzędzi i nie przynosi znacznie lepszych ulepszeń.

Powiązane problemy