Dlaczego ze wskazówek dotyczących wydajności Androida usunięto „Unikaj wyliczeń tam, gdzie potrzebujesz tylko Ints”?

175

Sekcja „Unikaj wyliczeń tam, gdzie potrzebujesz tylko Ints” została usunięta z oficjalnej dokumentacji programistów . (Zobacz Dlaczego Android nie używa więcej wyliczeń? Dla starej zawartości sekcji)

Czemu? Czy nastąpiła zmiana w maszynie wirtualnej z systemem Android, która spowodowała, że ​​wskazówka stała się przestarzała?

Thierry-Dimitri Roy
źródło
2
Dla porównania, oto zdekompilowany kod bajtowy dla przykładu Shrubbery: https://gist.github.com/847418
Josh Lee
15
Od marca 2014 r. Ta strona nadal zawiera porady dotyczące używania wyliczeń: developer.android.com/training/articles/memory.html#Overhead
Tahir Akhtar
2
Rok później, jak powiedział @TahirAkhtar, oficjalne szkolenie dotyczące Androida nadal mówi: „Należy bezwzględnie unikać używania wyliczeń na Androidzie”.
LarsH
1
Ciekawe jest to, że zalecenie unikania wyliczeń znajduje się w tym artykule z 2015 roku od głównego programisty Androida: medium.com/google-developers/ ... Ponadto: „Zauważ, że przy użyciu adnotacji @IntDef, która jest obsługiwana przez Android Studio i Gradle 1.3+, zapewni bezpieczeństwo typu w czasie kompilacji kodu (gdy włączone są błędy lint), zachowując jednocześnie korzyści związane z rozmiarem i wydajnością wynikające ze stosowania zmiennych int. "
tonylo
4
Od kwietnia 2018 r. Na tej stronie nie ma już porad dotyczących używania wyliczeń. developer.android.com/topic/performance/memory#Overhead
Robin Davies

Odpowiedzi:

157

oryginalna wersja tego dokumentu była tylko zbiorem uprzedzeń. został przepisany, aby zawierał tylko fakty poparte rzeczywistymi testami porównawczymi, i jest aktualizowany wraz z aktualizacją maszyny wirtualnej. różne testy porównawcze - a także niektóre testy porównawcze, których używamy do optymalizacji podstawowych bibliotek - można znaleźć pod adresem http://code.google.com/p/dalvik/ .

Elliott Hughes
źródło
35
Byłoby pomocne, gdybyś umieścił swoje poświadczenia w swoim profilu SO. Zajęło mi trochę czasu. Ale teraz, gdy widzę, że wydajesz się pracować w zespole VM, przyjmuję twoją odpowiedź jako oficjalną odpowiedź. :)
Thierry-Dimitri Roy
25
Dodanie klasy wyliczenia oznacza oczywiście, że aplikacja zawiera dodatkową klasę, więc nie jest darmowa , ale musimy założyć, że programista dodaje wyliczenia tylko wtedy, gdy są przydatne. Jedynym naprawdę złym zastosowaniem wyliczeń, jakie widziałem, był kod harmonii, w którym naprawdę chcieli int (dla masek bitowych i tym podobnych), a „wyliczenie” nie było wyliczeniem w jakimkolwiek sensownym sensie. Jeśli często nazywasz „porządkową ()”, prawdopodobnie jest to nieprzyjemny zapach, który oznacza, że ​​nie chcesz wyliczenia. Ale to nie jest wskazówka dotycząca Androida, a i tak jest to naprawdę rzadki błąd projektowy.
Elliott Hughes
17
Czy ten dokument również jest nieaktualny @ Thierry-DimitriRoy? W szczególności należy bezwzględnie unikać używania wyliczeń w systemie Android.
Jacob Tabak,
3
FWIW, Proguard domyślnie przekształci wyliczenia w wartości typu int .
Nacho Coloma
11
Link, który podałeś, jest martwy.
Terry
26

Przypuszczenie:

  • Procesory gigahercowe, takie jak Hummingbird i Snapdragon, są teraz powszechne, a wymagania dotyczące małej ilości pamięci, które pierwotnie ograniczały maszynę wirtualną Dalvik, nie są już tak prawdziwe.
  • Każde urządzenie wysyłkowe korzysta z JIT (nowość w wersji 2.2). Inicjator klasy wyliczenia będzie działał szybciej, wartości mogą być traktowane jako stałe czasu JIT, a JIT może mieć specjalne wsparcie dla usprawnienia klas wyliczeniowych.
  • Kod, który jest naprawdę wrażliwy na wydajność, wykorzystuje NDK, który był wciąż nowy i niedopracowany, gdy wypuszczono Androida 1.5. NDK w wersji 2.3 obsługuje działania natywne, co pozwala na prawie w pełni niezarządzane gry.

W związku z tym w przypadku stosunkowo przyziemnych wymagań aplikacji z interfejsem graficznym korzyści wynikające z wyliczeń w czasie projektowania znacznie przewyższają dodatkowy koszt czasu wykonywania.

Josh Lee
źródło
23

Elliott Hughes oferuje więcej szczegółów na temat przepisywania dokumentacji na swoim blogu: http://elliotth.blogspot.com/2010/09/java-benchmarks.html

W drugiej połowie postu wyjaśniono, że każde oświadczenie w dokumencie wydajności jest teraz poparte testami porównawczymi. Poprzednie wersje dokumentu najwyraźniej zawierały niezweryfikowane twierdzenia, na przykład „Unikaj wyliczeń, ponieważ są zbyt drogie”.

jkooker
źródło
Chciałem tylko uzupełnić zaakceptowaną odpowiedź Elliotta tym linkiem.
jkooker
12

W odpowiedzi z 2011 r. Elliota Huguesa stwierdzono, że pierwotnym powodem unikania wyliczenia była wydajność… jak w przypadku „wydajności przetwarzania”. Ponieważ ten powód nie był poparty faktami, został usunięty z oficjalnej dokumentacji.

Został dodany później, ponieważ wyliczenia dodają o wiele więcej danych do pamięci niż użycie liczb całkowitych.

Thierry-Dimitri Roy
źródło
2
Dodatkowo chłopaki z Google wprowadzili IntDefadnotacje, które pozwalają bezpiecznie używać stałych int z błędami i ostrzeżeniami Android Studio. blog.shamanland.com/2016/02/int-string-enum.html
Oleksii K.
9

TLDR: Dalvik nie radził sobie dobrze z alokacją pamięci i Enumzużywa więcej pamięci niż int. Android Lollipop zastąpił Dalvik ART, który nie ma takich samych ograniczeń. Dlatego to zalecenie nie ma już zastosowania.

Długa odpowiedź:

Łał! 8 lat, 5 odpowiedzi i wiele komentarzy później, prawdziwy powód nadal nie został rozwiązany.

W czasach prelollipop Android, Dalvik był procesem używanym jako maszyna wirtualna. Ponieważ w tym czasie dostępna była niewielka ilość pamięci dla aplikacji, w Dalvik było wiele ograniczeń pamięci. Aby przydzielić pamięć, Dalvik musiał przejść stos i znaleźć miejsce. Sterta również ulegała fragmentacji z czasem. Dalvik nie mógł zdefragmentować, więc przydzielałby go w czasie i ostatecznie zabrakło miejsca.

Unikaj wyliczeń tam, gdzie potrzebujesz tylko Ints

pochodzi z czasów Dalvik, ponieważ Enumjest dużo większy niż a, inta alokacja pamięci była bardzo droga.

W dzisiejszych czasach Dalvik został zastąpiony przez ART. ART pojawił się w KitKat i jest domyślny od Lollipopa.

ART został stworzony od podstaw nie po to, aby zoptymalizować pamięć, ale aby zoptymalizować wydajność. Jest również zoptymalizowany pod kątem alokacji i kolekcji. Powodem jest to, że ma pamięć zarezerwowaną dla dużych obiektów. Zamiast umieszczać wszystko w tej samej stercie, a następnie szukać miejsca na duże obiekty pośród wszystkich malutkich, ART umieszcza wszystkie duże obiekty i mapy bitowe w osobnej stercie. A potem małe przedmioty trafiają do oddzielnej sterty. Może również defragmentować.

Po ART, jeśli używasz EnumAndroida, to nie obchodzi i dlatego rekomendacja zniknęła.

To pochodzi od Cheta Haase'a z Google. Polecam znaleźć jego dyskusję Google I / O i obejrzeć cały film. Zawiera wiele przydatnych informacji i wgląd w Androida.

Adeel Ahmad
źródło