2009-10-23 14 views
12

Obecnie mam funkcję:Aby buforować lub nie buforować - GetCustomAttributes

public static Attribute GetAttribute(MemberInfo Member, Type AttributeType) 
{ 
    Object[] Attributes = Member.GetCustomAttributes(AttributeType, true); 

    if (Attributes.Length > 0) 
     return (Attribute)Attributes[0]; 
    else 
     return null; 
} 

Zastanawiam się, czy warto byłoby buforowanie wszystkie atrybuty na nieruchomości w słowniku Attribute = _cache[MemberInfo][Type],

ten wymagałoby użycia GetCustomAttributes bez żadnego parametru typu, a następnie wyliczenia z wyniku. Czy warto?

Odpowiedz

13

Dostaniesz lepsze huki dla dolców jeśli zastąpić ciało metodę z tym:

return Attribute.GetCustomAttribute(Member, AttributeType,false); // only look in the current member and don't go up the inheritance tree. 

Jeśli naprawdę trzeba buforować na typu zasadach:

public static class MyCacheFor<T> 
{ 
    static MyCacheFor() 
    { 
     // grab the data 
     Value = ExtractExpensiveData(typeof(T)); 
    } 

    public static readonly MyExpensiveToExtractData Value; 

    private static MyExpensiveToExtractData ExtractExpensiveData(Type type) 
    { 
     // ... 
    } 
} 

Beats wyszukiwanie słownika za każdym razem. Plus to threadsafe :)

Cheers, Florian

PS: Zależy jak często nazywają to.Miałem kilka przypadków, w których robi wiele serializacji przy użyciu odbicia naprawdę nazwie do buforowania, jak zwykle, operandi motus to:

  1. Zapis
  2. test
  3. Debug
  4. test ponownie
  5. CPU profil
  6. Mem profilu
  7. Optymalizacja
  8. test jeszcze raz
  9. CPU profilu
  10. MEM Profil Ten jest ważne, jak optymalizacji procesora związany kod pewnością przesunięcia ciężaru do pamięci
+0

Robię serializację za pomocą refleksji, więc wskazuje, że warto to zrobić w pewnym momencie. Jednak, jak wszyscy tutaj mówili - nie ma sensu optymalizować, dopóki nie pojawi się problem :) Pozdrawiam –

+4

W tym przypadku pozwól mi udostępnić podstęp: jeśli zamierzasz cache coś, gdzie twój klucz jest typu, użyj raczej rodzaj rodzajowy niż hashtable. Zaktualizowałem mój kod powyżej –

6

Jedynym sposobem na pewno na pewno jest profilowanie. Przepraszam, jeśli to brzmi jak banał. Ale powód, dla którego powiedzenie jest banałem, często jest taki, że jest prawdziwy.

Buforowanie tego atrybutu powoduje, że kod jest bardziej złożony i bardziej podatny na błędy. Więc możesz wziąć to pod uwagę - czas twojego rozwoju - zanim podejmiesz decyzję.

Tak jak optymalizacja, nie rób tego, chyba że musisz.

Z mojego doświadczenia (mówię o AutoCAD-like aplikacji Windows, z dużą ilością operacji GUI kliknij, edytować i liczba ciężkich pożerające), odczyt z atrybutu niestandardowego nie jest - nawet once-- wąskim gardłem wydajności .

+0

Alas mam żadnych narzędzi profilowania dostępne, aby móc przetestować rekwizyt erly. Prawdopodobnie jest to przedwczesne, ponieważ uważam, że jest to dość niska funkcja w mojej aplikacji, którą chciałem jak najlepiej wykorzystać. –

+0

Courtney: Możesz zrobić proste profilowanie, wywołując każdą implementację w pętli, która powtarza się wiele razy, i zmierzyć, jak długo każdy z nich wymaga uruchomienia. W tym przypadku nie potrzebujesz programu profilującego. –

3

Czy masz problem z wydajnością? Jeśli nie, nie rób tego, dopóki go nie potrzebujesz.

Może to pomóc w zależności od tego, jak często wywoływana jest metoda z tymi samymi parametrami. Jeśli wywołasz tylko jeden raz na kombinację MemberInfo, Type, to nie przyniesie to żadnego pożytku. Nawet jeśli robisz pamięć podręczną, masz tendencję do zwiększania zużycia pamięci. To może być dobre dla twojej aplikacji.

5

Twoje pytanie dotyczy przypadku przedwczesnej optymalizacji.

Nie znasz wewnętrznego działania klas refleksji, a zatem przyjmujesz założenia dotyczące implikacji związanych z wydajnością wielokrotnego wywoływania GetCustomAttributes. Sama metoda może dobrze buforować już swoje wyniki, co oznacza, że ​​Twój kod rzeczywiście zwiększy obciążenie bez poprawy wydajności.

Oszczędzaj cykle mózgowe, myśląc o rzeczach, o których wiesz, że są problemami!

+0

Właściwie zamierzałem powiedzieć w pytaniu, ale skończyłem je edytować, nie wiem, czy robi to wewnętrznie. –

0

miałem tylko scenariusz, w którym GetCustomAttributes okazał się wąskim gardłem wydajności . W moim przypadku był wywoływany setki tysięcy razy w zbiorze danych z wieloma wierszami, co sprawiało, że problem był łatwy do wyizolowania. Buforowanie atrybutów rozwiązało problem.

Wstępne testy doprowadziły do ​​ledwo zauważalnego uderzenia wydajności w około 5000 połączeń na współczesnym komputerze. (I stało się drastycznie bardziej zauważalne, gdy rozmiar zbioru danych wzrósł).

Ogólnie zgadzam się z innymi odpowiedziami na temat przedwczesnej optymalizacji, jednak w skali instrukcji CPU do wywołania DB, sugeruję, że GetCustomAttributes pochyliłoby się bardziej w kierunku tego ostatniego.

Powiązane problemy