Por que "Evitar enums onde você só precisa de ints" foi removido das dicas de desempenho do Android?

175

A seção "Evitar enums onde você só precisa de ints" foi removida da documentação oficial do desenvolvedor . (Consulte Por que o Android não usa mais enumerações? Para o conteúdo da seção antiga)

Por quê? Houve uma alteração na VM do Android que tornou a dica obsoleta?

Thierry-Dimitri Roy
fonte
2
Para referência, aqui é o decompiled bytecode para o exemplo Shrubbery: https://gist.github.com/847418
Josh Lee
15
Em março de 2014, a seguinte página ainda contém conselhos contra o uso de enums: developer.android.com/training/articles/memory.html#Overhead
Tahir Akhtar
2
Um ano depois, como disse @TahirAkhtar, o treinamento oficial para Android ainda diz "Você deve evitar estritamente o uso de enums no Android".
Larsh
1
Interessante notar que a recomendação para evitar enum está neste artigo de 2015 de um desenvolvedor Android líder: medium.com/google-developers/… Também: "Observe que usando a anotação @IntDef, suportada pelo Android Studio e Gradle 1.3+, dará segurança ao seu tipo de código no momento da criação do código (quando os erros de cotão estiverem ativados), mantendo os benefícios de tamanho e desempenho do uso de variáveis ​​int ".
tonylo
4
Em abril de 2018, a página a seguir não contém mais conselhos sobre o uso de enumerações. developer.android.com/topic/performance/memory#Overhead
Robin Davies

Respostas:

157

a versão original desse documento era apenas um monte de preconceitos. foi reescrito para conter apenas fatos com backup de benchmarks reais e é atualizado à medida que a VM é atualizada. você pode encontrar os vários benchmarks - além de alguns que usamos para otimizar as principais bibliotecas - em http://code.google.com/p/dalvik/ .

Elliott Hughes
fonte
35
Seria útil se você listasse suas credenciais no seu perfil de SO. Demorei um pouco para cavar. Mas agora que vejo que você parece trabalhar na equipe de VM, aceitarei sua resposta como a resposta oficial. :)
Thierry-Dimitri Roy
25
Adicionar uma classe de enumeração significa que seu aplicativo contém uma classe extra, portanto não é gratuita , mas devemos assumir que um desenvolvedor está adicionando enumerações apenas quando úteis. O único uso realmente ruim que eu vi de enums foi em algum código de harmonia em que eles realmente queriam ints (para máscaras de bits e afins) e o "enum" não era um enum em nenhum sentido razoável. Se você se chama muito de "ordinal ()", provavelmente é um mau cheiro que significa que você não quer enum. Mas essa não é uma dica específica do Android, e é um erro de design muito raro.
22712 Elliott Hughes
17
É este documento fora da data, bem @ Thierry-DimitriRoy? Especificamente, você deve evitar estritamente o uso de enumerações no Android.
Jacob Tabak
3
FWIW, Proguard transformará enums em ints por padrão.
Nacho Coloma
11
O link que você deu está morto.
Terry
26

Um palpite:

  • Atualmente, as CPUs Gigahertz, como Hummingbird e Snapdragon, são comuns, e os requisitos de memória pequena de código pequeno que originalmente restringiam a Dalvik VM não são mais tão verdadeiros.
  • Todo dispositivo de remessa usa o JIT (novo em 2.2). O inicializador de classe do enum será executado mais rapidamente, os valores poderão ser tratados como constantes de tempo JIT e o JIT poderá ter um suporte especial para a otimização de classes de enum.
  • O código realmente sensível ao desempenho usa o NDK, que ainda era novo e não polido quando o Android 1.5 foi lançado. O NDK na 2.3 suporta atividades nativas, o que permite jogos quase totalmente não gerenciados.

Assim, para os requisitos comparativamente mundanos de um aplicativo GUI, os benefícios de enums em tempo de desenvolvimento superam em muito o custo extra de tempo de execução.

Josh Lee
fonte
23

Elliott Hughes oferece mais detalhes sobre a documentação reescrita em seu blog: http://elliotth.blogspot.com/2010/09/java-benchmarks.html

A segunda metade da postagem explica que agora todas as reivindicações no documento Desempenho são copiadas com referências. As versões anteriores do documento aparentemente continham reivindicações não verificadas, como "Evite enumerações porque são muito caras".

jkooker
fonte
Só queria complementar a resposta aceita de Elliott com este link.
Jkooker
12

A resposta de Elliot Hugues em 2011 disse que o motivo original para evitar enum era por razões de desempenho ... como em "desempenho de processamento". Como esse motivo não foi apoiado pelo fato, ele foi removido da documentação oficial.

Ele foi adicionado posteriormente porque as enumerações adicionam muito mais dados na memória do que o número inteiro.

Thierry-Dimitri Roy
fonte
2
Além disso, os caras do Google introduziram IntDefanotações, que permitem usar constantes int com segurança com os erros e avisos do Android Studio. blog.shamanland.com/2016/02/int-string-enum.html
Oleksii K.
9

TLDR: Dalvik não era bom com alocação de memória e Enumusa mais memória que int. O Android Lollipop substituiu o Dalvik pelo ART, que não sofre as mesmas limitações. Portanto, essa recomendação não é mais relevante.

A resposta longa:

Uau! 8 anos, 5 respostas e muitos comentários depois, o verdadeiro motivo ainda não foi abordado.

Nos dias pré-pirulito para Android, Dalvik era o processo usado pela VM. Como havia pouca quantidade de memória disponível para os aplicativos usarem durante esse período, a Dalvik apresentava muitas restrições de memória. Para alocação de memória, Dalvik teve que andar pela pilha e encontrar espaço. O heap também seria fragmentado ao longo do tempo. Dalvik não pôde desfragmentar, para alocar com o tempo e, eventualmente, ficar sem espaço.

Evite enums onde você só precisa de ints

vem dos dias de Dalvik porque um Enumé muito maior que um inte a alocação de memória era muito cara.

Hoje em dia, Dalvik foi substituído pelo ART. O ART foi lançado no KitKat e é o padrão desde o Lollipop.

O ART foi criado desde o início não para otimizar a memória, mas otimizar o desempenho. Também é otimizado para alocações e cobranças. A razão é que ela tem memória reservada para objetos grandes. Em vez de colocar tudo no mesmo heap e, em seguida, ter que encontrar espaço para objetos grandes entre todos os pequenos, o ART coloca todos os objetos grandes e bitmaps em um heap separado. E então os pequenos objetos vão para a pilha separada. Também pode desfragmentar.

Após a TARV, se você usa o EnumAndroid, não se importa e é por isso que a recomendação foi embora agora.

Isto vem de Chet Haase no Google. Eu recomendo encontrar a conversa dele no Google I / O e assistir o vídeo inteiro. Ele contém muitas informações úteis e informações sobre o Android.

Adeel Ahmad
fonte