14
Geração Automática de Código Android Eficiente a partir de Modelos UML Abilio Gambim Parada, Aline Rodrigues Tonini, Lisane Brisolara de Brisolara Ciência da Computação, Grupo de Arquiteturas e Circuitos Integrados, Centro de Desenvolvimento Tecnológico, Universidade Federal de Pelotas, Brasil {agparada, artonini, lisane}@inf.ufpel.edu.br Resumo. Dispositivos móveis vêm substituindo computadores para uma série de aplicações. Um grande número destes aparelhos utilizam a plataforma Android da Google. Este crescimento na utilização de dispositivos móveis tem impulsionado o mercado de desenvolvimento de aplicações para estes dispositivos. Entretanto, devido ao curto tempo de lançamento do produto no mercado, abordagens que visam acelerar o desenvolvimento são necessárias. Para diminuir o tempo de desenvolvimento e ao mesmo tempo suportar projetos complexos, abordagens de engenharia baseada em modelos, ou MDE (Model- drivenEngineering), estão sendo utilizadas. No entanto, os desenvolvedores devem se preocupar também em atender requisitos não funcionais relacionadas a desempenho e consumo de energia inerentes ao domínio. Neste contexto, a Google propôs um conjunto de boas práticas e técnicas de programação para aplicações Android, tendo como principal objetivo o desempenho das aplicações. Este artigo propõe uma abordagem MDE para geração automática de código, a qual aplica boas práticas Android, visando à geração de código eficiente. A abordagem é demonstrada através de um estudo de caso, no qual a melhoria obtida com as práticas adotadas pode ser observada. Palavras Chaves: Android, UML, boas práticas, desempenho, geração de código, MDE. 1 Introdução A crescente utilização de dispositivos móveis, como smartphones e tablets, tem se tornado uma alternativa à utilização de computadores de uso pessoal, impulsionado assim o mercado destes eletrônicos. Dentre as várias plataformas disponíveis no

Geração Automática de Código Android Eficiente a partir de ... · uma abordagem dedicada para a modelagem dos aplicativos e ferramentas capazes de transformar modelos UML em código

Embed Size (px)

Citation preview

Geração Automática de Código Android Eficiente a

partir de Modelos UML

Abilio Gambim Parada, Aline Rodrigues Tonini, Lisane Brisolara de Brisolara

Ciência da Computação, Grupo de Arquiteturas e Circuitos Integrados,

Centro de Desenvolvimento Tecnológico,

Universidade Federal de Pelotas, Brasil

{agparada, artonini, lisane}@inf.ufpel.edu.br

Resumo. Dispositivos móveis vêm substituindo computadores para uma série

de aplicações. Um grande número destes aparelhos utilizam a plataforma

Android da Google. Este crescimento na utilização de dispositivos móveis tem

impulsionado o mercado de desenvolvimento de aplicações para estes

dispositivos. Entretanto, devido ao curto tempo de lançamento do produto no

mercado, abordagens que visam acelerar o desenvolvimento são necessárias.

Para diminuir o tempo de desenvolvimento e ao mesmo tempo suportar projetos

complexos, abordagens de engenharia baseada em modelos, ou MDE (Model-

drivenEngineering), estão sendo utilizadas. No entanto, os desenvolvedores

devem se preocupar também em atender requisitos não funcionais relacionadas

a desempenho e consumo de energia inerentes ao domínio. Neste contexto, a

Google propôs um conjunto de boas práticas e técnicas de programação para

aplicações Android, tendo como principal objetivo o desempenho das

aplicações. Este artigo propõe uma abordagem MDE para geração automática

de código, a qual aplica boas práticas Android, visando à geração de código

eficiente. A abordagem é demonstrada através de um estudo de caso, no qual a

melhoria obtida com as práticas adotadas pode ser observada.

Palavras Chaves: Android, UML, boas práticas, desempenho, geração de

código, MDE.

1 Introdução

A crescente utilização de dispositivos móveis, como smartphones e tablets, tem se

tornado uma alternativa à utilização de computadores de uso pessoal, impulsionado

assim o mercado destes eletrônicos. Dentre as várias plataformas disponíveis no

mercado surge a plataforma Android [1], como uma solução completa de código livre

com um amplo suporte aos mais diversos dispositivos, bem como ferramentas de

apoio ao desenvolvimento e sistema operacional.

Aplicativos Android trazem novas características para a programação tanto no

estilo quanto em peculiaridades que devem ser observadas. Uma destas características

é a programação orientada a eventos, pois estes aplicativos devem constantemente

reagir a interações do usuário [2], e também conceitos adicionais como ciclo de vida e

a utilização de determinada estrutura de acordo com o comportamento da

aplicação.Estas novas características aumentam a dificuldade do desenvolvimento de

aplicativos Android. Além disso, desenvolvedores devem se preocupar também com a

eficiência e um melhor aproveitamento dos recursos do dispositivo. Considerando

estas particularidades e o fato de existir pessoas de vários lugares do mundo com

maneiras diferentes de programar desenvolvendo aplicações para Android, a Google

propõe o uso de “Boas Práticas” no processo de desenvolvimento [3], para assim

viabilizar um melhor desempenho das aplicações Android.

Além de todas as características de desenvolvimento e de boas práticas que devem

ser consideradas, as aplicações Android estão fortemente ligadas ao mercado

possuindo um curto tempo de desenvolvimento. Tradicionalmente, abordagens de

Engenharia Dirigida por Modelos ou MDE (do inglês, Model Driven Engineering)

vem sendo adotadas, principalmente por que oferecem abstração através do uso de

modelos e automação através de transformação de modelos, facilitando e acelerando o

desenvolvimento [4]. Segundo um estudo realizado na Motorola, a MDE pode reduzir

em até 70% o tempo de produção de software [5].

Entretanto o uso efetivo do paradigma MDE no desenvolvimento Android, requer

uma abordagem dedicada para a modelagem dos aplicativos e ferramentas capazes de

transformar modelos UML em código Android. Para resolver este problema, em [6],

foi proposta uma abordagem para modelagem e geração de código. Entretanto esta

abordagem não aplica técnicas de otimização de código, dessa forma, este artigo

estende esta abordagem para a geração de código Android eficiente através da

aplicação das boas práticas propostas pela Google. Nossa abordagem é demonstrada e

os resultados de desempenho são discutidos através de um estudo de caso.

Este artigo está organizado da seguinte forma. A Seção 2 apresenta a

fundamentação teórica, enquanto a Seção 3 apresenta e discute trabalhos

relacionados. Na seção 4, a abordagem proposta para geração de código eficiente é

detalhada e o estudo de caso que demonstra resultados de seu emprego é apresentado

na Seção 5. As conclusões do trabalho são discutidas na Seção 6.

2 Boas práticas Android

A Google sugere uma série de “Boas Práticas” para o desenvolvimento de aplicativos

Android. Estas boas práticas são dicas simples de programação que aplicadas aos

hábitos de codificação proporcionam um melhor desempenho geral da aplicação. Esta

seção introduz estas boas práticas bem como destaca o seu impacto no desempenho,

segundo o estudo realizado pela Google em [3].

Uma das boas práticas indicadas pela Google é evitar a criação de objetos

desnecessários, pois a criação destes é sempre custosa. A alocação de objetos em

excesso faz com que a coleta de lixo seja realizada periodicamente, o que tem um

impacto negativo no desempenho da aplicação.

Outra prática sugerida é preferir o uso de métodos estáticos ao invés de virtuais.

Desta forma, métodos que não irão acessar campos do objeto devem ser declarados

como estáticos. De acordo com o estudo da Google, invocações estáticas serão de

15% a 20 % mais rápidas.

Neste conjunto de boas práticas, é recomendado o uso de static final para

constantes, pois ao usar a palavra reservada final na definição de constantes os

acessos serão mais rápidos. Isso se deve ao fato da classe não requerer o método

<clinit>, visto que constantes são armazenadas em um campo do arquivo .dex

responsável pela inicialização das constantes. Porém, esta recomendação é válida

somente para tipos primitivos e Strings constantes.

Em linguagens orientadas a objeto como C++ e Java é comum o uso de getter para

acessar atributos ao invés de acessá-los diretamente. Porém esta não é uma prática

recomendável para Android, pois as chamadas a métodos virtuais são muito mais

caras do que o acesso direto ao campo. Desta forma, é recomendado que o uso de

getters e setters seja evitado. De acordo com a Google, o tempo para acessar um

atributo diretamente é três vezes mais rápido do que através de um getter sem o

recurso de JIT (Just-in-time) e cerca de sete vezes mais rápido com o uso do JIT.

A sintaxe do for aprimorado ou for-each pode ser usada para definir coleções que

implementam uma interface iterativa para Arrays. Com as coleções é alocado um

iterador que faz chamadas a hashNext e next. De acordo com a Google o uso da

sintaxe aprimorada do for em Arrays é três vezes mais rápido (com ou sem o uso de

JIT) comparado com o uso do for com iterador explícito.

É possível iterar uma matriz de três maneiras, como mostram os trechos de código

abaixo. A maneira como zero itera a matriz é mais lenta, pois o JIT não otimiza a

maneira de obter o comprimento da matriz a cada iteração do laço. A iteração usada

em one é mais rápida, pois utiliza variáveis locais e o comprimento da matriz oferece

um beneficio de desempenho. A implementação da sintaxe aprimorada do for,

introduzida no Java 1.5, realizada em two é a mais rápida em dispositivos sem JIT e

indiferente de one para dispositivos com JIT. É possível iterar uma matriz de três

maneiras, como mostra o trecho de código abaixo:

Códigos com várias implementações de for

static class Foo {

intmSplat;

}

Foo[] mArray = ...

public void zero(){

int sum = 0;

for (int i = 0; i<mArray.length; ++i){

sum + = mArray[i].mSplat;

}

}

public void one(){

int sum = 0;

Foo[] localArray = mArray;

intlen = localArray.length;

for (int i = 0; i<len; ++i){

sum + = localArray[i].mSplat;

}

}

public void two(){

int sum = 0;

for( Foo : a ){

sum + = a.mSplat;

}

}

As boas práticas também indicam o uso de acesso do tipo pacote (package) ao

invés do tipo privado (private) em classes internas privadas. Esta prática se aplica

quando uma classe interna a outra (inner class) precisa acessar atributos da classe

externa. A máquina virtual considera o acesso direto da classe interna a membros

privados da classe externa como sendo ilegal, porque são classes diferentes. Para

evitar esse problema atributos e métodos que devem ser acessados por classes internas

devem ter visibilidade do tipo pacote, indicada pelo modificador public, protected ou

sem nenhum modificador [7]. Ao aplicar a prática sugerida, evita-se uma sobrecarga

em aplicações que utilizam classes internas em pontos críticos de desempenho. Outra

boa prática é evitar o uso de Ponto Flutuante, pois de acordo com a Google, o seu uso

em dispositivos Android é cerca de duas vezes mais lento do que o uso de inteiros.

3 Trabalhos Relacionados

Muitos trabalhos preocupam-se com a eficiência de aplicações para dispositivos

móveis [8][9][10]. Em [8] os autores discutem a sobrecarga no desempenho induzida

pelo uso da abstração em camadas para software embarcado, usando como plataforma

alvo o Android. Em [9], um conjunto de benchmarks foram implementados de

diferentes formas no Android e avaliados quanto ao desempenho. Os resultados

mostraram uma sobrecarga do Java-Android comparado a implementações C rodando

na mesma plataforma. Da mesma forma, em [10] são realizados experimentos com

diferentes implementações de algoritmos e são analisados resultados de desempenho e

energia consumida pelas implementações quando executadas no Android. Porém,

nenhum destes trabalhos considera as boas práticas. Apenas em [11] o impacto destas

práticas no desempenho do software foi avaliado através de experimentos.

Como este ainda é um campo de atuação novo, há um número bastante reduzido de

ferramentas que proveem a geração automática de código para dispositivos Android a

partir de modelos de alto nível de abstração. A IBM recentemente adicionou à

ferramenta Rational Rhapsody [12] um perfil para aplicações Android. No entanto,

sua abordagem exige que a aplicação seja definida em um nível baixo de detalhe para

que a geração de código seja realizada. Além da IBM, observam-se esforços da

Google e da Eclipse. A Google propôs o App Inventor [13] e a Eclipse, o AndroMate

[14], ambas focam na modelagem gráfica e geração para Android. No entanto, tanto o

AndroMate como o App Inventor poderiam ser classificados como programação

visual ao invés de orientados a modelos. Ainda deve-se ressaltar que nenhuma destas

abordagens considera boas práticas ou inclui passos de otimização no momento da

geração de código. Nossa abordagem difere-se das abordagens utilizadas por estas

ferramentas, pois procura minimizar os detalhes que devem ser inseridos pelo

projetista no modelo e aplica boas práticas automaticamente durante a geração de

código, suportando assim a geração de código eficiente para a plataforma Android.

4 Geração de Código Android Eficiente

A geração automática de código Android eficiente proposta neste trabalho baseia-se

na aplicação das boas práticas propostas pela Google para dispositivos Android.

Assim como proposto em [6], nossa abordagem gera código Java-Android a partir de

modelos UML construídos usando suas notações padrão, sendo esta transformação

suportada por uma ferramenta em desenvolvimento pelo grupo. Durante a geração de

código, a ferramenta aplica as boas práticas, visando a obtenção de código otimizado

para a plataforma Android, evitando que o projetista tenha que refatorar o código para

incluir estas otimizações manualmente. Estas otimizações são opcionais de forma que

o usuário pode escolher quais otimizações serão aplicadas, para assim observar os

impactos destas otimizações de forma isolada.

A entrada da ferramenta de geração de código é um modelo UML, composto de

diagramas de classe e de sequência, construídos de acordo com a abordagem

apresentada em [6]. O diagrama de classe oferece a visão estrutural, a partir da qual

código estrutural pode ser gerado. Já os diagramas de sequência são usados na

geração de código comportamental. A Seção 4.1 apresenta a geração estrutural de

código eficiente para a plataforma Android, enquanto a geração comportamental é

detalhada na Seção 4.2. Atualmente, nossa ferramenta implementa três das boas

práticas sugeridas pelo Google. Destas, uma afeta apenas a geração estrutural, outra

apenas a geração comportamental e outra modifica ambas as gerações.

4.1 Geração Estrutural

Na geração de código estrutural, são geradas definições de atributos (nome, tipo e

visibilidade), de métodos (nome, parâmetros e visibilidade) e importação de pacotes.

Duas das boas práticas são aplicadas na geração do código estrutural.

A primeira delas se refere a geração dos atributos e se baseia na boa prática que

sugere o uso dos modificadores static e static final para constantes. Quando um

atributo tem um valor de inicialização, este é classificado como constante pela

ferramenta. Neste caso, a ferramenta aplica a boa prática, gerando a declaração com o

modificador mais apropriado. Se a constante for do tipo primitivo ou String, é usado o

static final, caso contrário, apenas o modificador static é usado. Esta boa prática traz

benefícios na velocidade de acesso a estas constantes, proporcionando assim um

melhor desempenho para o sistema, como discutido na Seção 2.

A segunda boa prática aplicada na geração refere-se à definição e geração de

métodos de acesso a atributos, os métodos getters e setters. Na primeira versão da

ferramenta, sem foco na otimização, para todo o atributo era gerado um método getter

e um método setter, mesmo que estes métodos não estivessem explicitados no modelo

da classe. No entanto, esta prática é contrária a uma das boas práticas do Google que

propõe o acesso direto aos atributos sem métodos getters e setters como forma de

melhorar o desempenho do código. A eliminação destes métodos pode requerer

mudanças na visibilidade do atributo para permitir que o mesmo seja acessado

diretamente, e também a eliminação da invocação do método de acesso. Desta forma,

esta boa prática não afeta apenas a geração do código estrutural, mas também afeta a

geração de código comportamental (discutida na Seção 4.2).

Na geração estrutural, nossa ferramenta realiza a análise dos atributos e métodos

de acesso descritos no modelo antes da geração propriamente dita do código. Caso

seja identificado um atributo privado (private ou protect) para o qual métodos de

acesso tenham sido definidos no modelo, a ferramenta irá gerar a definição do

atributo como público (public) e não fará a definição dos métodos de acesso

correspondentes. Para isto é necessário que o projetista siga a boa prática indicada

para programação em geral, de utilizar nomes para métodos de acesso contendo o

nome do atributo a ser acessado [15] com prefixo get ou set.

4.2 Geração Comportamental

Na geração do código comportamental das aplicações Android, a aplicação da boa

prática de eliminação de chamadas aos métodos getters e setters deve ser concluída.

Para tal, a ferramenta deve analisar os diagramas de sequência para identificar onde

são utilizados estes métodos de acesso, para posteriormente substituir a invocação do

método por uma atribuição ou leitura do atributo.

Neste trabalho, também propomos a aplicação da boa prática relativa à utilização

da sintaxe do for apropriada, apresentada na Seção 2. Para aplicação desta boa prática,

a ferramenta deve analisar os diagramas de sequência do modelo, com especial

atenção naqueles onde um fragmento do tipo loop é usado, o qual representa uma

iteração. A análise para determinar a melhor sintaxe do for considera o que está sendo

utilizado dentro da estrutura de iteração.Caso seja iterado uma coleção de objetos é

indicado pelas boas práticas a utilização da sintaxe for-each, enquanto que para a

manipulação de um simples vetor é indicado a utilização do for-lenght. Desta forma,

com base nas características do modelo, a ferramenta escolhe a melhor sintaxe de

acordo com as boas práticas para o uso do for apresentadas na Seção 2.

5 Estudo de Caso

Para demonstrar a nossa abordagem bem como os resultados obtidos pelo uso das

boas práticas, esta seção apresenta um estudo de caso. Neste estudo, primeiramente, a

aplicação Snake é modelada em UML, seguindo a nossa abordagem de modelagem

proposta em [6] e realizando a engenharia reversa do código original da aplicação.

Posteriormente, este modelo é usado como entrada para a ferramenta GenCode, a qual

gera o código a aplicação. A aplicação escolhida está disponível no site de apoio ao

desenvolvedor Android [16]. Apesar de ser uma aplicação simples, ela permite a

demonstração dos principais aspectos da abordagem, bem como apontar as melhorias

alcançadas com a aplicação das boas práticas.

Neste estudo é demonstrada a geração de trechos de código da aplicação, focando

nos pontos do código onde as práticas foram aplicadas. Primeiramente, será

demonstrada a aplicação da eliminação de getters e setters, que conforme explicado

na Seção 4, é realizada pelas duas rotinas de geração de código, estrutural e

comportamental. Após, será demonstrada a aplicação da boa prática do for. Para

facilitar a visualização das melhorias aplicadas pela geração, o código original será

comparado com o código automaticamente gerado pela ferramenta. O código gerado

inclui a aplicação de boas práticas (em separado) e a comparação entre estes dois

códigos permite observar o impacto das otimizações. Além disso, análises de

desempenho também foram realizadas, permitindo a comparação entre os códigos.

A Figura 1 ilustra a visão estática da aplicação, representada pelo diagrama de

classes. Nesta figura são destacadas as classes Activity, View e Handler, pertencentes

ao Android. A partir das informações obtidas neste diagrama, o código estrutural foi

gerado. Como a eliminação de getters e setters foi habilitada, a ferramenta realizou a

análise de atributos e de seus métodos de acesso. Esta busca identificou o método

setTextView da classe Snake, contexto onde a boa prática que evita getters e setters

deveria ser aplicada. Abaixo, são apresentados os trechos do código original e do

código gerado, após a captura e análise do diagrama. O código original define o

atributo como privado (modificador private) e declara o método de acesso, bem como

o corpo deste método. Já o código gerado automaticamente declara este atributo como

público (usando o modificador public) e não faz a declaração do método setTextView.

Fig. 1. Diagrama de classe, representação estrutural da aplicação Snake.

Trecho de código original da aplicação Snake utilizando setter

private TextView textView;

public void setTextView(TextView textView) {

this.textView = textView;

}

Trecho de código da aplicação Snake utilizando a prática que evita getters e setters

public TextView textView;

Para a eliminação do método setTextView, porém, a ferramenta realizou uma busca

entre os diagramas de sequência a fim de identificar onde este método era invocado.

Para então, substituir esta invocaçãopor uma atribuição. Sem a otimização, o código

que seria gerado a partir do modelo comportamental, incluiria a invocação do método

setTextView(), conforme trecho de código abaixo.

Trecho de código original da classe SnakeView, invocação do método de acesso

mSnakeView.setTextView(findViewById(R.id.text));

Enquanto que com a aplicação da boa prática, a rotina de geração do código

comportamental faz a busca pela invocação do método a ser eliminado e substitui a

sua chamada pelo acesso direto ao atributo, gerando o trecho de código abaixo.

Trecho de código da classe SnakeView, utilizando a prática que evita getters e setters

mSnakeView.textView = findViewById(R.id.text);

Para a comparação da eficiência do código gerado pela nossa ferramenta com o

código original do aplicativo, foi utilizada a ferramenta DDMS (Dalvik Debug

Monitor Server) [17], que fornece resultados relativos ao tempo de execução de

códigos Android. A DDMS gera CPU Include Time, o qual considera o tempo de

execução do método analisado incluindo o tempo dos métodos chamados por este, e o

CPU Exclude Time, que por sua vez, considera apenas o tempo de execução do

método em análise. Todos os experimentos realizados e discutidos nesta seção foram

repetidos 30 vezes, e a partir dos tempos de execução obtidos, uma média foi

calculada, a qual é utilizada nas comparações realizadas.

Os resultados obtidos pela análise de desempenho dos dois códigos são

apresentados no gráfico ilustrado na Fig. 2, onde o eixo y representa o tempo da CPU

em milissegundos (ms). Esta análise de desempenho considera o CPU Include Time

fornecido pela DDMS, pois o custo da chamada do método de acesso deve ser

contabilizado, neste caso. O tempo médio de execução do fragmento do código

original (Fig. 2) foi de 0,8444 ms e o desvio padrão foi de 0,0276 ms, enquanto o

tempo de execução do código gerado foi de 0,8030 ms e o desvio padrão de 0,30 ms.

Foi utilizado o teste estatístico “t de student” para comparação de médias, sendo a

diferença entre as médias considerada estatisticamente significativa. Neste gráfico,

observa-se que o tempo de execução foi reduzido em 4,9029% pela aplicação da boa

prática que evita o uso de getters e setters, o que demostra o impacto real da

utilização desta boa prática.

Fig. 2. Gráfico representando a diferença de desempenho na utilização de métodos de acesso.

Neste estudo de caso, a aplicação da boa prática da escolha da sintaxe do for

também é demonstrada. Esta boa prática é tratada apenas pela rotina de geração de

código comportamental. Durante esta rotina, laços devem ser identificados nos

diagramas de sequência. Para demonstrar sua aplicação é usada a representação de

0,720,740,760,78

0,80,820,840,860,88

Incl

CP

U T

ime

(m

s)

Comparação Com Setter - Sem Setter

Com Setter

Sem Setter

uma pequena parcela do modelo comportamental do Snake ilustrado na Figura 3. Este

diagrama de sequência se refere ao detalhamento do método enqueueDirection

proveniente da classe SnakeView. Neste diagrama pode-se observar o uso de um laço

de iteração no qual o objeto mNextDirectionArray é iterado. O laço é representado

pelo fragmento loop. Outro fragmento interno a este, do tipo opt, representa uma

condicional, que restringe a invocação do método add(direction).

Fig. 3. Diagrama de sequência do método enqueueDirection da classe SnakeView.

Com base nas informações contidas neste diagrama, a ferramenta aplica a boa

prática e determina qual a sintaxe apropriada para a implementação da manipulação

do Array mNextDirectionArray. Neste caso, a ferramenta escolhe o uso do for-each,

devido ao uso de um Array junto a um laço. Abaixo são apresentados os

fragmentosreferente ao laço. No código original o for normal é usado, enquanto no

código gerado pela ferramenta, o for-each é usado.

Trecho de código original da aplicação Snake, utilizando a sintaxe normal do for

private void enqueueDirection(int direction) {

int c=mNextDirectionArray.size();

for (int i=0; i<c; i++) {

if (mNextDirectionArray.get(i)==0) {

mNextDirectionArray.add(i,direction);

break;

}

}

}

Trecho de código gerado aplicando a boa prática do for-each

private void enqueueDirection(int direction) {

for (Integer c : mNextDirectionArray) {

if (c.equals(0)) {

mNextDirectionArray.add(direction);

break;

}

}

}

Para demonstrar a melhoria em desempenho obtida pela aplicação desta

otimização, foram realizados experimentos após a geração do código (considerando

apenas esta otimização). Os resultados de desempenho do código original e código

gerado são ilustrados no gráfico da Fig. 4. A análise de desempenho neste caso,

considera o CPU Exclude Time fornecido pela DDMS, pois apenas o custo do laço

deve ser contabilizado, não incluindo o custo da chamada do método addDirection().

Pode-se observar que o tempo médio de execução com o for normal (código original)

foi de 59,0882 mscom desvio padrão de 1,5526 ms, enquanto o resultado utilizando o

for-each (código gerado), foi de 12,4501ms, tendo o desvio padrão de 0,5249 ms.

Valores médios de tempo de execução foram usados nestacomparação e a diferença

entre as médias também foi considerada estatisticamente significativa.

Fig. 4. Desempenho obtido pelo for normal e pelo for-each

6 Conclusões

Este artigo apresenta uma abordagem MDE para geração automática de código

Android eficiente a partir de modelos UML. A geração de código aplica

0

10

20

30

40

50

60

70

Excl

CP

u T

ime

(m

s)

Comparação For Normal - For Each

For Normal

For - Each

automaticamente boas práticas do Google, com o objetivo de melhorar o desempenho

do código gerado. Esta geração foi prototipada em uma ferramenta de geração de

código chamada GenCode [6]. A automatização destas otimizações evita que o

projetista tenha de estudar as boas práticas e refatorar o código implementado para

que este faça uso destas práticas e, portanto, tenha o desempenho melhorado. A

abordagem é demonstrada com um estudo de caso, que também é usado para

evidenciar as melhorias no desempenho obtidas com a geração de código proposta.

Além da eficiência do código gerado, outros benefícios podem ser vinculados ao

emprego desta abordagem, dentre estes destaca-se a abstração oferecida pelo uso de

modelos UML e a automação provida pela ferramenta de geração. Além disso, a

abordagem proposta utiliza notações padrão da UML, o que evita a necessidade do

uso de uma ferramenta de modelagem específica.

O uso do diagrama de sequência limita a geração de código comportamental

proposta até o nível de chamada de métodos, que é o que pode ser expresso neste

diagrama. Para obter código completo, outros diagramas precisam ser considerados na

geração de código. Atualmente, nossa ferramenta implementa três das boas práticas

sugeridas pelo Google. Como trabalhos futuros, pretendemos analisar a viabilidade de

estender esta abordagem para outras boas práticas, priorizando aquelas que

apresentam maior impacto no desempenho.

Referências

1.Google. (2012) Fundamentos de uma aplicação Android. Disponível em:

http://developer.android.com/guide/components/fundamentals.html. Acesso em: Dezembro,

2012.

2.Kraemer, F. A. et al., “Engineering android applications based on UML activities”,

Proceedings of the 14th international conference on Model driven engineering languages

and systems (MODELS’11), Jon Whittle, Tony Clark, and Thomas Khne (Eds.). Springer-

Verlag, Berlin, Heidelberg, pp. 183–197, 2011.

3.Google. (2012) Boas práticas para performance. Disponível em:

http://developer.android.com/training/best-performance.html. Acesso em: Dezembro, 2012.

4.Selic, B. “Models, software models, and UML”, UML for real: Design of embedded real time

systems, vol. Boston: Kluwer Academic Publishers, pp. 1–16, 2003.

5.Weigert, T. “Practical experiences in using model-driven engineering to develop

trustworthy,” Computing Systems. IEEE International Conference on Sensor Networks,

Ubiquitous, and Trustworthy Computing, vol. 1 (SUTC’06), 2011.

6.Parada, A., Brisolara, L.: A model driven approach for Android application development.

SBESC, Brazilian Symposium on Computing System Engineering, Natal, 2012.

7.Oracle. (2012) Controlling Access to Members of a Class. Disponível em:

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html. Acesso em:

Dezembro, 2012.

8.Camara, V. B., Corrêa, U. B. Performance Overhead from the Usage of Software Abstraction

on Complex Embedded Systems. SBESC, Brazilian Symposium on Computing System

Engineering, Florianópolis, 2011.

9.Batyuk, L., et al. (2009) “Developing and Benchmarking Native Linux Applications on

Android” in Mobile Wireless Middleware, Operating Systems, and Applications. 2009.

10.Vieira et al. Análise de desempenho e consumo energético para aplicações embarcadas na

Plataforma Android. SBESC, Brazilian Symposiumon Computing System Engineering,

Natal, 2012.

11.Beckmann, M. Avaliação das Boas Práticas de Codificação para Plataforma Android.

Trabalho de conclusão de curso. UFPel.

12.IBM. (2012) Rational Rhapsody. Disponível em:

http://www.ibm.com/software/awdtools/rhapsody/. Acesso em: Dezembro, 2012.

13.MIT. (2012) App Inventor. Disponível em: http://appinventor.mit.edu/. Acesso em:

Dezembro, 2012.

14.Telematica Instituut. (2012) The android modeller and code generator. Disponível em:

http://www.lab.telin.nl/_msteen/andromate/. Acesso em: Dezembro, 2012.

15.Martin, R..: Clean Code: A hand book of Agile Software Craftsmanship, , Pearson, Boston,

(2009).

16.Google. (2012) Exemplos de Aplicações Android em:

http://developer.android.com/tools/samples/index.html. Acesso em: Dezembro, 2012.

17.Google. (2012) Using DDMS. Disponível em:

http://developer.android.com/tools/debugging/ddms.html. Acesso em: Dezembro, 2012