Założę się, że mógłbym sam na to odpowiedzieć, gdybym wiedział więcej o narzędziach do analizy zachowania C # / JIT, ale ponieważ nie, proszę o wyrozumiałość.
Mam prosty kod taki jak ten:
private SqlMetaData[] meta;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private SqlMetaData[] Meta
{
get
{
return this.meta;
}
}
Jak widać, umieściłem AggressiveInlining, ponieważ uważam, że powinienem być podkreślony.
Myślę. Nie ma żadnej gwarancji, że JIT wprowadziłby to inaczej. Czy się mylę?
Czy robienie tego rodzaju rzeczy może zaszkodzić wydajności / stabilności / czegokolwiek?
c#
performance
meta-programming
Serge
źródło
źródło
Odpowiedzi:
Kompilatory to inteligentne bestie. Zwykle automatycznie wyciskają jak najwięcej wydajności z dowolnego miejsca.
Próba przechytrzenia kompilatora zwykle nie robi dużej różnicy i ma duże szanse na odwrót. Na przykład wstawianie powoduje, że Twój program jest większy, ponieważ wszędzie kopiuje kod. Jeśli twoja funkcja jest używana w wielu miejscach w całym kodzie, może faktycznie być szkodliwa, jak wskazano @CodesInChaos. Jeśli jest oczywiste, że funkcja powinna być wbudowana, możesz się założyć, że kompilator to zrobi.
W przypadku wahania możesz nadal robić oba i porównywać, jeśli występuje jakiś wzrost wydajności, to jedyny pewny sposób na teraz. Ale założę się, że różnica będzie nieistotna, kod źródłowy będzie po prostu „głośniejszy”.
źródło
struct
s jako parametry - w wielu przypadkach powinien i powinien. Oprócz pominięcia setek oczywistych optymalizacji - w tym między innymi - unikania niepotrzebnych kontroli granic i alokacji między innymi.Masz rację - nie ma sposobu, aby zagwarantować, że metoda zostanie wstawiona - Wyliczenie metody MSDN MethodImplOptions , SO MethodImplOptions.AggressiveInlining vs. TargetedPatchingOptOut .
Programiści są bardziej inteligentni niż kompilator, ale pracujemy na wyższym poziomie, a nasze optymalizacje są produktami pracy jednego człowieka - naszej. Jitter widzi, co dzieje się podczas egzekucji. Może analizować zarówno przepływ wykonania, jak i kod zgodnie z wiedzą wprowadzoną przez jego projektantów. Możesz lepiej poznać swój program, ale lepiej znają CLR. A kto będzie bardziej poprawny w swoich optymalizacjach? Nie wiemy tego na pewno.
Dlatego powinieneś przetestować każdą dokonaną optymalizację. Nawet jeśli jest to bardzo proste. I weź pod uwagę, że środowisko może się zmienić, a Twoja optymalizacja lub dezoptymalizacja może przynieść całkiem nieoczekiwany rezultat.
źródło
EDYCJA: Zdaję sobie sprawę, że moja odpowiedź nie odpowiedziała dokładnie na pytanie, podczas gdy nie ma prawdziwego minusa, z moich wyników czasowych też nie ma prawdziwej plusu. Różnica między wbudowanym narzędziem do pobierania właściwości wynosi 0,002 sekundy ponad 500 milionów iteracji. Mój przypadek testowy może również nie być w 100% dokładny, ponieważ używa struktury, ponieważ istnieją pewne zastrzeżenia do fluktuacji i podkreślenia struktur.
Jak zawsze, jedynym sposobem, aby naprawdę wiedzieć, jest napisanie testu i wymyślenie go. Oto moje wyniki z następującą konfiguracją:
Opróżnij projekt z następującymi ustawieniami:
Wyniki
Testowane z tym kodem:
źródło
Kompilatory wykonują wiele optymalizacji. Inlining jest jednym z nich, niezależnie od tego, czy programista chciał, czy nie. Na przykład MethodImplOptions nie ma opcji „wbudowanej”. Ponieważ wstawianie jest automatycznie wykonywane przez kompilator w razie potrzeby.
Wiele innych optymalizacji jest szczególnie wykonywanych, jeśli włączono je w opcjach kompilacji, lub zrobi to tryb „wydania”. Ale te optymalizacje są w pewnym sensie „działały dla Ciebie, świetnie! Nie działały, zostaw to” optymalizacje i zwykle dają lepszą wydajność.
jest tylko flagą kompilatora, że naprawdę pożądana jest tutaj operacja wstawiania. Więcej informacji tutaj i tutaj
Odpowiedzieć na Twoje pytanie;
Prawdziwe. Bez gwarancji; Żaden C # nie ma opcji „wymuszania”.
W tym przypadku nie, jak powiedziano w piśmie Pisanie aplikacji zarządzanych o wysokiej wydajności: podkład
źródło