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?


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/ .


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.


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”.


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.


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.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.