Geração Automática de Código Android Eficiente a partir de Modelos UML Abilio Gambim Parada Aline Rodrigues Tonini Lisane Brisolara de Brisolara Grupo de Arquiteturas e Circuitos Integrados - GACI Universidade Federal de Pelotas - UFPel Pelotas-Brasil 1 / 43 Sumário 1 Introdução 2 Geração de Código 3 Estudo de Caso 4 Conclusões 2 / 43 Introdução Alternativa ao uso de computadores pessoais Crescente demanda no mercado por novos aplicativos Existem várias plataformas para dispositivos móveis: Symbian, Android, iOS, BlackBerry... 3 / 43 Introdução O desenvolvimento de aplicativos para dispositivos móvies também trazem preocupações extras como: Eficiência! Estas aplicações devem fazer um bom uso dos recursos do dispositivo Um aspecto importante é o desempenho da aplicação! 4 / 43 Introdução Visando um melhor desempenho de aplicativos, frequentemente são adotadas algumas boas práticas Boas práticas: dicas para obter a melhor forma de realizar uma tarefa A Google propos um conjunto de boas práticas para Android com este objetivo! 5 / 43 Motivação Android Uma das plataformas mais utilizadas Desenvolvida pela Google Solução completa de código livre Suporte a vários dispositivos Ferramentas de apoio ao desenvolvedor 6 / 43 Motivação A Google indica uma serie de boas práticas para obter um melhor desempenho das aplicações Android, como: 1 2 Evitar a criação de objetos desnecessários Preferir métodos estáticos, invocação 15% a 20% mais rápidos É recomendado a definição de constantes como static Para as de tipo primitivo e String static final 7 / 43 Motivação 4 Evitar o uso de métodos getters e setters O tempo de acesso direto ao atributo é três vezes mais rápido 5 Sintaxe apropriada para o for 6 Visibilidade package para classe interna 8 / 43 Motivação Java Máquina virtual Dalvik, no lugar da tradicional JVM Constante reação com as interações do usuário Programação orientada a eventos e serviços Caracterı́sticas estas que aumentam a complexidade do projeto! 9 / 43 Motivação MDE: Engenharia Dirigida por Modelos Modelos principal artefato na construção do sistema Utiliza UML como linguagem padrão de modelagem Abstração, automação, foco no problema, rapidez no desenvolvimento, produtividade, corretudo, manutenção Diminui em 70% o tempo de desenvolvimento, segundo estudos realizados na Motorola em 2007 Ferramentas de apoio para geração de código a partir de modelos 10 / 43 Geração de Código Abordagem proposta Geração de código Android eficiente, aplicando as boas práticas, baseado em MDE Utiliza diagramas de Classe e de Sequência Permite representação estrutural e comportamental do sistema Considera as caracterı́sticas Android, propondo modelagem especial para estas Aplica boas práticas de desempenho durante a geração de código 11 / 43 Geração de Código 12 / 43 Modelagem Estrutural A estrutura da aplicação é representada por Diagrama de Classe UML Classes, atributos, operações e relacionamentos Na modelagem estrutural Android também é observado componetes como Activity e Service! 13 / 43 Activity Activity é utilizado para representar a tela de um aplicativo (ex: como a interface de um player de audio) Métodos para Activity: onCreate onStart onResume onPause onStop onDestroy ... 14 / 43 Service Service é responsável por atividades que executam em segundo plano, podendo estas serem padrão ou do usuário (ex: a atividade de tocar o audio) Métodos para Service: onCreate onStart onBind onDestroy ... 15 / 43 Modelagem Estrutural Definição de Activity e Service como subclasses Relacionamento de especialização Indicação no modelo quais métodos serão customizados 16 / 43 Geração de Código Estrutural A geração para métodos como Activity e Service difere de métodos normais Para estes métodos, código padrão pode ser gerado conforme as particularidades de cada método Exemplo: Método onCreate de uma Activity; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } 17 / 43 Boas práticas estruturais Na geração estrutural da aplicação Android são aplicadas boas práticas como: Modificadores static e static final static para constantes static final para tipos primitivos e String Eliminação de métodos de acesso (getters e setters) e modificação da visibilidade do atributo 18 / 43 Modelagem Comportamental O comportamento da aplicação é representado por Diagramas de Sequência UML: Troca de mensagens, iterações, condicionais . . . Além disso, em Android temos conceitos como: Intent: fornece acesso a um recurso (ex: Bluetooth); 19 / 43 Modelagem Comportamental Criação da Intent a ser usada Invocação do método. Intent intent = new Intent(BluetoothDevice.ACTION FOUND); startActivity(intent); 20 / 43 Boas práticas comportamentais Na geração comportamental também são aplicadas boas práticas como: Substituição da invocação dos métodos getters e setters Escolha da sintaxe apropriada para o for for-each: para coleções for-length: para vetores 21 / 43 Estudo de Caso Aplicação Snake, código livre disponı́vel no site de apoio ao desenvolvedor Android Engenharia reversa Modelos construidos na ferramenta Papyrus Comparação de desempenho do código original e o código automaticamente gerado com as otimizações 22 / 43 Estudo de Caso: Metodologia Para avaliar da eficiência entre os códigos foi utilizada a ferramenta DDMS (Dalvik Debug Monitor Server) A DDMS fornece resultados relativos ao tempo de execução do código Android CPU Include Time: considera o tempo de execução do método analisado, incluindo os métodos chamados por este CPU Exclude Time: considera apenas o tempo de execução do método analisado 23 / 43 Estudo de Caso: Metodologia Testes executados na plataforma Android 4.1.2 Todos os testes foram repetidos 30 vezes, obtendo assim uma média, utilizada nas comparações realizadas Para avaliar se a comparação das médias é válida, foi utilizado o teste estatı́stico “t de student” 24 / 43 Estudo de Caso: Visão Estrutural Representada por diagrama de Classe Classes Android destacas em cinza Relacionamento de epecialização/generalização 25 / 43 Estudo de Caso: Código Estrutural Trecho de código original, setter : private TextView textView; ... public void setTextView(TextView textView){ this.textView = textView; } Trecho de código gerado aplicando a boa prática: public TextView textView; 26 / 43 Estudo de Caso: Código Comportamental Trecho de código original, invocação do método de acesso: mSnakeView.setTextView(findViewById(R.id.text)); Trecho de código gerado aplicando a boa prática: mSnakeView.textView = findViewById(R.id.text); 27 / 43 Estudo de Caso: Desempenho Avaliação da boa prática de método de acesso 1 Incl CPU Time (ms) 0.84 0.8 0.8 0.6 0.4 0.2 0 Com Setter Sem Setter Sem Setter melhora de 4.76% no desempenho 28 / 43 Estudo de Caso: Visão Comportamental Representada por diagramas de sequência Comportamento do método enqueueDirection Iterações, condicionais, troca de mensagens 29 / 43 Estudo de Caso: Código Comportamental Trecho de código original: private void enqueueDirection (int direction) { for(int i=0; i < mNextDirectionArray.size(); i++) if(mNextDirectionArray.get(i) == 0) { mNextDirectionArray.add(i,direction); break; } } } 30 / 43 Estudo de Caso: Código Comportamental Trecho de código aplicando a boa prática for-length: private void enqueueDirection (int direction) { int count = mNextDirectionArray.length(); for(int i=0; i < count; i++) if(mNextDirectionArray.get(i) == 0) { mNextDirectionArray.add(i,direction); break; } } } 31 / 43 Estudo de Caso: Código Comportamental Trecho de código aplicando a boa prática for-each: private void enqueueDirection (int direction) { for(Integer count: mNextDirectionArray) if(count.equals(0)) { mNextDirectionArray.add(direction); break; } } } 32 / 43 Estudo de Caso: Desempenho Avaliação entre as sintaxes para for 82.27 Excl CPU Time (ms) 80 59.08 60 40 20 12.45 For normal For-length For-each 33 / 43 Estudo de Caso: Desempenho Melhora no desempenho do for-length e for-each em comparação com for normal 84.86 For normal % 80 60 40 28.18 For-length For-each 34 / 43 Conclusões Este trabalho apresenta uma abordagem MDE para geração de código Android Considera as caracterı́sticas Android Aplica automaticamente boas práticas Geração de código otimizado fornecendo abstração para o desenvolvedor Visão Estrutural: Diagrama de Classe Visão Comportamental: Diagrama de Sequência 35 / 43 Trabalhos Futuros Diagramas de sequência limitam a geração de código comportamental proposto até o nı́vel de chamada de método Para obter código completo outros diagramas precisam ser considerados na geração de código Atualmente é implementado três das boas práticas sugeridas pela Google Estender a abordagem para considerar outras boas práticas 36 / 43 Agradecimentos Suporte Financeiro CNPq NESS (PRONEX-10/0043-0) 37 / 43 Geração Automática de Código Android Eficiente a partir de Modelos UML ¡Muchas gracias! Abilio Gambim Parada [email protected] 38 / 43 Dados Boa prática Setter Testes 1 2 3 4 5 6 7 .. . Com Setter 0.872 0.821 0.825 0.841 0.874 0.821 0.85 .. . Sem Setter 0.789 0.842 0.804 0.790 0.763 0.789 0.784 .. . 28 29 30 Média σ 0.884 0.842 0.846 0.8444 0.0275 0.807 0.764 0.807 0.8029 0.0299 39 / 43 Dados Boa prática Setter Com Setter – Sem Setter Valor p: Diferença entre Médias Intervalo de Confiança a 95% 0.0001 0.0414666666000 0.0265818245330 to 0.0563515086670 Conclusão: A diferença é extremamente significativa Testes executados na plataforma Android 4.1.2 40 / 43 Dados Boa prática For Testes 1 2 3 4 5 6 7 .. . For Normal 57.703 63.043 59.34 56.348 58.079 57.112 59.555 .. . For-Lenght 81.729 81.646 80.752 82.582 85.546 84.011 80.695 .. . For-Each 12.644 11.69 12.324 12.277 13.402 12.225 12.024 .. . 28 29 30 Média σ 58.714 60.621 61.237 59.0882 1.5527 83.429 80.841 81.531 82.2773 1.5566 12.237 12.649 13.543 12.4500 0.5248 41 / 43 Dados Boa prática For For Normal – For Lenght Valor p: Diferença entre Médias Intervalo de Confiança a 95% 0.0001 23.1890666667000 22.3855308061390 to 23.9926025272610 Conclusão: A diferença é extremamente significativa Testes executados na plataforma Android 4.1.2 42 / 43 Dados Boa prática For For Normal – For Each Valor p: Diferença entre Médias Intervalo de Confiança a 95% 0.0001 13215.11239999670 46.0391481703574 to 47.2371851628426 Conclusão: A diferença é extremamente significativa Testes executados na plataforma Android 4.1.2 43 / 43