Tutorial para Programadores de Modelos
JAMS Componentes-API
Tipos de dados JAMS
Os seguintes tipos de dados do JAMS estão disponíveis:
- Attribute.Boolean
- Attribute.BooleanArray
- Attribute.Calendar
- Attribute.DirName
- Attribute.Document
- Attribute.Double
- Attribute.DoubleArray
- Attribute.Entity
- Attribute.EntityCollection
- Attribute.FileName
- Attribute.Float
- Attribute.FloatArray
- Attribute.Geometry
- Attribute.Interger
- Attribute.IntegerArray
- Attribute.Long
- Attribute.LongArray
- Attribute.Object
- Attribute.String
- Attribute.StringArray
- Attribute.TimeIntervall
Componentes JAMS
O principal fundamento de qualquer modelo JAMS é o assim denominado componente. Um componente é uma classe de JAVA que implementa três métodos diferentes (a saber, init,run e cleanup), que são acionados em fases de execução correspondentes, através das quais um modelo JAMS itera. Como indicado pelos seus nomes, estes métodos são ativados no início, durante e no final da vida útil de um componente. Embora os métodos “init” e “clean” sejam executados apenas uma vez, o método de execução “run” pode ser ativado várias vezes, dependendo do objetivo e da configuração do componente.
A comunicação entre a estrutura (o framework) e os outros componentes é realizada por atributos públicos arbitrários, que devem satisfazer duas condições: (i) ser de um tipo de dados JAMS válido e (ii) ser marcados por anotações especiais JAVA, ou seja, meta-informação sintática. Estas anotações de atributo são usadas para definir o seu tipo I/O (read, write), o seus valores padrões, a unidade física e limites (se numéricos), e um pequeno texto descrevendo o finalidade do atributo. Estas informações são usadas tanto para que o sistema de execução possa criar e interligar atributos e para que os GUIs possam fornecer ajuda durante o design do modelo.
Componentes de Contexto JAMS
Um contexto JAMS é um componente especial composto de várias partes, que pode integrar outros componentes e contextos, que são então chamados de “filhotes”. Um contexto serve dois propósitos principais: (i) controlar a execução de seus filhotes, e (ii) servir como armazenamento de dados para os seus filhotes, permitindo uma troca de dados flexível entre eles. Dependendo da finalidade de um dado contexto, ele pode acionar seus filhotes várias vezes ao longo de um número de iterações (Figura à esquerda), mas apenas uma vez, se alguma condição pré-definida estiver satisfeita (Figura ao centro) ou apenas uma vez em uma sequência (Figura à direita). Já que contextos são componentes especializados, eles podem estar integrados em outros contextos, permitindo a formação de complexas hierarquias de componentes e estruturas para o controle de execuções . A figura a seguir mostra exemplos de contexto.
Entrada / Saída de Dados JAMS
Dados I/O no JAMS podem ser processados de duas maneiras diferentes. Como uma primeira opção, um componente pode ser usado para ler ou gravar dados a partir de qualquer fonte de dados, por exemplo, arquivos ou bancos de dados. Neste caso, o programador dos componentes deve encarregar-se em solicitar todas as informações necessárias através dos dados de entrada do componente (como por exemplo, nomes de arquivos), ter acesso a fonte de dados e fornecer potenciais resultados (por exemplo, fazer a leitura de dados de um arquivo), assim como dados de saída. Uma vantagem dessa abordagem é um elevada flexibilidade no acesso à informação externa. Por outro lado, esses componentes geralmente precisam ser adaptados a determinados modelos e formatos de dados, o que limita a sua reutilização.
A segunda opção para o processamento da troca de dados no JAMS é o uso da interface de software DataStore. Esta interface pode ser utilizada para ler / gravar dados de / em um armazenamento de dados externo, o qual pode ser um arquivo, ou um sistema de bancos de dados ou um recurso de rede. Ele fornece funções para ler e gravar conjuntos de dados, cada um representado por uma lista ordenada de objetos de dados. Os objetos de dados são descritos por metadados, contendo, por exemplo, seu tipo, limites e significado. A figura a seguir dá uma visão geral da estrutura do DataStore JAMS, mostrando dois tipos de DataStore para a leitura (InputDataStore) e gravação (OutputDataStore) de dados. No caso do InputDataStore, métodos podem ser utilizados para solicitar (hasNext) e recuperar (getNext) os dados disponíveis (DataSet). Da mesma forma, o OutputDataStore fornece métodos para gravar dados no dispositivo de armazenamento subjacente.
Os tipos de dados suportados representam os dados disponíveis JAMS e incluem dados numérios, tipos string e calendário, e geometrias espaciais. A fim de representar a último, o JAMS faz uso do padrão do Simple Feature Access, tal como definido pelo Open Geospatial Consortium.
Para acessar os dados de um DataStore, sua última fonte de dados e o software para acessá-lo devem ser identificados e parametrizados. Isso é feito por documentos XML especiais. Cada um destes define um DataStore e serve às seguintes finalidades:
(1) identificar e parametrizar um componente de software I/O que, no final das contas, pode vir a acessar um certo tipo de fonte de dados,
(2) definir uma ou mais fontes de dados para serem acessadas por esse componente, e no caso de um InputDataStore:
(3) definir como os dados recuperados serão formatados e apresentados.
Os componentes de software I/O podem ser fornecidos pelo usuário e são disponibilizados para o JAMS através de um plug-in mecanismo. Como exemplo, esta poderia ser uma classe de Java que é capaz de ler arquivos com o formato ASCII contendo informações de séries temporais. Parâmetro pode ser o nome do arquivo e o tamanho do buffer de leitura.
Desenvolvimento de Componentes JAMS
Instalação de um ambiente de Desenvolvimento
Pode-se baixar o ambiente de desenvolvimento NetBeans na página http://netbeans.org gratuitamente. A última versão é a NetBeans IDE 6.9.1. Selecione Java SE, JavaFX, Java ou Todos(all) como o IDE NetBeans Download package. Além disso, o Java Development Kit (JDK) é necessário e pode ser baixado em http://www.oracle.com/technetwork/java/javase/downloads/index.html.
Seu ambiente de desenvolvimento NetBeans fica assim depois de iniciá-la:
Baixando códigos-fonte de JAMS/J2000 da Internet
Os códigos-fonte de Java JAMS/J2000 e os vários componentes-padrão, incluindo todas as bibliotecas necessárias, podem ser baixados em http://www.geoinf.uni-jena.de/5580.0.html, usando o link: JAMS-2 16-src.tgz.
As pastas-fonte a seguir estão incluídas:
Configuração Projetos no NetBeans
Os projetos devem ser integrados na seguinte ordem:
Passo 1 - Integrando o Projeto JAMS
Primeiramente, os códigos-fonte JAMS/J2000 têm de ser carregadas no Netbeans. Nesta primeira etapa, o projeto JAMS é configurado. Para tal, abra o NetBeans e selecione Novo Projeto sob o item de menu Arquivo.
A seguinte janela irá aparecer:
Já que é necessário integrar um código fonte existente, selecione Java Project with Existing Source. Clique em Next (próximo). Na segunda etapa, é preciso fornecer um nome e uma pasta de projeto. Dê ao projeto o nome JAMS. A pasta do projeto é inserida como uma pasta-padrão, mas ela pode ser modificada. Clique em Next.
Clicando no botão Add Folder é preciso carregar os seguintes códigos-fonte para o projeto:
- JAMSapi
- JAMScommon
- JAMSExplorer
- JAMSMain
- JAMSRemote
- JAMSstarter
- JAMSui
Clique em Finish.
Na próxima etapa, as bibliotecas necessárias para o projeto precisam ser carregadas. Para encontrá-las na pasta-fonte baixada, sob JAMS-2_x-src \ ext. (X representa a versão que está atualmente baixada, e que muda com o tempo). Clique com o botão direito do mouse no “Projeto JAMS”, no projeto JAMS gerado. Selecione o ponto Properties.
Selecione o item Libraries na parte direita da janela Project Properties - JAMS sob Categories. Usando o botão Add JAR / Folder as bibliotecas necessárias podem ser carregadas. Carregue todas as bibliotecas que estão disponíveis na pasta-fonte baixada JAMS-2_x-src \ ext.
O projeto JAMS foi criado com sucesso.
Se desejar compilar o projeto, clique com o botão direito do mouse sobre o projeto JAMS e selecione o item Build and Clean. O JAMS.jar será gerado. Na janela inferior esquerda da seu ambiente de desenvolvimento NetBeans, pode-se verificar se o processo foi bem sucedido e onde a JAMS.jar foi salva.
Passo 2 - Integrando o Projeto J2000
Integre o projeto J2000, como descrito no primeiro passo, como novo projeto com códigos-fonte existentes. Os códigos-fonte estão no diretório já também baixado ...\JAMS-x-src\J2K\src.
Carregue como biblioteca o JAMS.jar criado no primeiro passo.
Compile o novo projeto clicando com o botão direito do mouse sobre o projeto J2000 e selecionando o item de menu Build and Clean. Na janela inferior direita do seu ambiente de desenvolvimento NetBeans, deverá constar BUILD SUCCESSFUL.
Passo 3 - Integrando o Projeto JAMSComponents
Integre o projeto JAMSComponents como novo projeto com códigos-fonte existentes como descrito no passo 1. Os códigos-fonte estão no diretório ...\JAMS-x-src\JAMSComponents\src, o qual também já está baixado.
Carregue como biblioteca o JAMS.jar que foi gerado no primeiro passo, bem como todas as bibliotecas (*. jar - Files) da pasta ...\JAMS-x-src\ext.
Compile o novo projeto clicando com o botão direito do mouse sobre o projeto J2000 e selecionando o item de menu Build and Clean. Na janela inferior direita do seu ambiente de desenvolvimento NetBeans, deverá constar BUILD SUCCESSFUL.
Iniciando componentes de processo a partir do NetBeans
Cada componente de processo que tenha um procedimento principal pode ser iniciado diretamente a partir do NetBeans. Como exemplo, iniciaremos diretamente JAMSLauncher, como descrito em detalhes no Tutorial Usuários Iniciantes.
Principais Classes
Clicando com o botão direito do mouse sobre o projeto JAMS'. Escolha o item de menu Properties. Clique em run na parte esquerda da janela. A janela a seguir deve aparecer:
No campo Main Class (classe principal), escreva a classe que deve ser iniciada durante a execução do projeto. Com um único clique no botão Browse …, todas as Main Classes disponíveis no projeto são mostrados. Esses são todos os componentes que têm um procedimento principal (Main procedure). Escolha entre as seguintes classes para iniciar as interfaces de usuário JAMS maiores:
- Jamsui.launcher.JAMSui para o JAMS Launcher
- Jamsui.juice.JUICE para o JAMS Builder
Selecione a classe desejada com Select Main Class e confirme pressionando OK. Inicie agora o projeto JAMS, clicando com o botão direito do mouse sobre o projeto, em seguida, escolha o item run. A interface de usuário escolhida será iniciada. Desta forma, várias classes com um procedimento principal podem ser iniciadas.
Desenvolvimento de novos Componentes de Processo em JAVA
Estrutura de um Componente
Cada componente do processo JAMS é estruturado da seguinte forma:
1. Nome do pacote. Ele é gerado automaticamente pelo NetBeans.
package org.unijena.j2k.interception;
2. Importação de bibliotecas / classes que são necessárias para os componentes do processo.
import jams.data.*; import jams.model.*;
...
3. Iniciando o componente do processo. Cada componente do processo começa com uma descrição dos componentes. Desta forma podem ser armazenados no código-fonte metainformações sobre o componente. Informações sobre o título do componente, o autor, a versão e a data de modificação devem estar incluídas. Além disso, uma breve descrição do componente é necessária.
@JAMSComponentDescription(
title="...",
author="...",
description="...",
version="...",
date="..."
)
public class NewClass {
4. Conjunto de variáveis com variáveis públicas e privadas. As variáveis públicas podem ser acessados a partir de outras classes dentro de um modelo. Para cada variável, comentários públicos na forma de anotações são incluídas no código-fonte.
O tipo de acesso (AccessType) deve ser escolhido entre JAMSVarDescription.AccessType.READ (variáveis que são apenas lidas), JAMSVarDescription.AccessType.WRITE (variáveis são apenas salvas) ou JAMSVarDescription.AccessType.READWRITE (variáveis que são lidas e salvas).
Além disso, uma breve descrição, bem como uma unidade de medida (se possível) e um limite inferior e superior da variável são necessários.
@JAMSVarDescription(
access=... ,
description="...",
unit="...",
lowerBound=...,
upperBound=...
)
public JAMSDouble var1;
@JAMSVarDescription(
access=... ,
description="...",
unit="...",
lowerBound=...,
upperBound=...
)
public JAMSInteger var2;
@JAMSVarDescription(
access=... ,
description="...",
unit="...",
lowerBound=...,
upperBound=...
)
public JAMSString var3;
...
private JAMSDoublr var4;
...
Todas as classes JAMS ou J2000 dispõem dos procedimentos init (), run () e cleanup ().
5. O procedimento de inicialização é executado durante a inicialização do modelo.
public void init() throws JAMSEntity.NoSuchAttributeException{
...
}
6. O procedimento (run) é realizado brevemente durante a execução do modelo.
public void run() throws JAMSEntity.NoSuchAttributeException{
...
}
7. O procedimento de limpeza (cleanup) é realizado no final de uma execução de modelo.
public void cleanup() throws JAMSEntity.NoSuchAttributeException{
...
}
8. Procedimentos particulares e funções. Estes só estão disponíveis dentro do componente de processo.
private double funktion1(double var){
...
return ...;
}
9. Fim do componente de processo.
}
Exemplo de um Componente de Processo Completo
1. Nome do pacote
package org.unijena.j2k.potET;
2. Bibliotecas importadas
import java.io.*; import jams.data.*; import jams.model.*;
3. Iniciando o componente de processo. Cada componente de processo começa com uma descrição dos componentes. Desta forma, novos metadados do componente podem ser armazenados no código-fonte. Ele deve incluir informações sobre o título do componente, o autor, a versão e a data de modificação. Além disso, uma breve descrição do componente é necessária.
@JAMSComponentDescription(
title=""CalcDailyETP_PenmanMonteith"",
author="Peter Krause",
description="Calculates potential ETP according Penman-Monteith",
version="1.0_0",
date="2011-04-11"
)
public class Penman extends JAMSComponent {
4. Conjunto de variáveis com variáveis públicas e privadas. As variáveis públicas podem ser acessadas a partir de outras classes dentro de um modelo. Para cada variável, comentários públicos na forma de anotações são incluídos no código-fonte.
O tipo de acesso (AccessType) deve ser escolhido entre JAMSVarDescription.AccessType.READ (variáveis que são apenas lidas), JAMSVarDescription.AccessType.WRITE (variáveis são apenas salvas) ou JAMSVarDescription.AccessType.READWRITE (variáveis que são lidas e salvas).
Além disso, uma breve descrição, bem como uma unidade de medida (se possível) e um limite inferior e superior da variável são necessários.
@JAMSVarDescription(access = JAMSVarDescription.AccessType.READ, description = "Current time") public JAMSCalendar time; @JAMSVarDescription(access = JAMSVarDescription.AccessType.READ, description = "temporal resolution [d | h | m]") public JAMSString tempRes; @JAMSVarDescription(access = JAMSVarDescription.AccessType.READ, description = "state variable wind") public JAMSDouble wind; @JAMSVarDescription(access = JAMSVarDescription.AccessType.READ, description = "state variable mean temperature") public JAMSDouble tmean; @JAMSVarDescription(access = JAMSVarDescription.AccessType.READ, description = "state variable relative humidity") public JAMSDouble rhum; @JAMSVarDescription(access = JAMSVarDescription.AccessType.READ, description = "state variable net radiation") public JAMSDouble netRad; @JAMSVarDescription(access = JAMSVarDescription.AccessType.READ, description = "attribute elevation") public JAMSDouble elevation; @JAMSVarDescription(access = JAMSVarDescription.AccessType.READ, description = "attribute area") public JAMSDouble area; @JAMSVarDescription(access = JAMSVarDescription.AccessType.WRITE, description = "potential ET [mm/ timeUnit]") public JAMSDouble potET; @JAMSVarDescription(access = JAMSVarDescription.AccessType.WRITE, description = "actual ET [mm/ timeUnit]") public JAMSDouble actET; @JAMSVarDescription(access = JAMSVarDescription.AccessType.READ, description = "et calibration parameter") public JAMSDouble et_cal; @JAMSVarDescription(access = JAMSVarDescription.AccessType.READ, defaultValue = "0") public JAMSInteger dataCaching; private File cacheFile; transient private ObjectOutputStream writer; transient private ObjectInputStream reader; public final double CP = 1.031E-3; //konstanter Parameter public final double RSS = 150; //konstanter Parameter
5. O procedimento de inicialização é realizado durante a inicialização do modelo.
public void init() throws JAMSEntity.NoSuchAttributeException, IOException {
cacheFile = new File(getModel().getWorkspace().getTempDirectory(), this.getInstanceName() + ".cache");
if (!cacheFile.exists() && (dataCaching.getValue() == 1)) {
getModel().getRuntime().sendHalt(this.getInstanceName() + ": dataCaching is true but no cache file available!");
}
if (dataCaching.getValue() == 1) {
reader = new ObjectInputStream(new BufferedInputStream(new FileInputStream(cacheFile)));//new FileInputStream(cacheFile));
} else if (dataCaching.getValue() == 0) {
writer = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(cacheFile)));
}
}
6. O procedimento (run) é realizado durante a execução do modelo. public void run () throws JAMSEntity.NoSuchAttributeException, IOException {
public void run() throws JAMSEntity.NoSuchAttributeException, IOException {
if (dataCaching.getValue() == 1) {
this.potET.setValue(reader.readDouble());
this.actET.setValue(0.0);
} else {
double netRad = this.netRad.getValue();
double temperature = this.tmean.getValue();
double rhum = this.rhum.getValue();
double wind = this.wind.getValue();
double elevation = this.elevation.getValue();
double area = this.area.getValue();
double abs_temp = org.unijena.j2k.physicalCalculations.ClimatologicalVariables.calc_absTemp(temperature, "degC");
double delta_s = org.unijena.j2k.physicalCalculations.ClimatologicalVariables.calc_slopeOfSaturationPressureCurve(temperature);
double pz = org.unijena.j2k.physicalCalculations.ClimatologicalVariables.calc_atmosphericPressure(elevation, abs_temp);
double est = org.unijena.j2k.physicalCalculations.ClimatologicalVariables.calc_saturationVapourPressure(temperature);
double ea = org.unijena.j2k.physicalCalculations.ClimatologicalVariables.calc_vapourPressure(rhum, est);
double latH = org.unijena.j2k.physicalCalculations.ClimatologicalVariables.calc_latentHeatOfVaporization(temperature);
double psy = org.unijena.j2k.physicalCalculations.ClimatologicalVariables.calc_psyConst(pz, latH);
double G = this.calc_groundHeatFlux(netRad);
double vT = org.unijena.j2k.physicalCalculations.ClimatologicalVariables.calc_VirtualTemperature(abs_temp, pz, ea);
double pa = org.unijena.j2k.physicalCalculations.ClimatologicalVariables.calc_AirDensityAtConstantPressure(vT, pz);
double tempFactor = 0;
double pET = 0;
double aET = 0;
if (this.tempRes.getValue().equals("d")) {
tempFactor = 86400;
} else if (this.tempRes.getValue().equals("h")) {
tempFactor = 3600;
} else if (this.tempRes.getValue().equals("m")) {
tempFactor = 86400;
}
double Letp = 0;
Letp = this.calcPM(delta_s, netRad, G, pa, CP, est, ea, psy, tempFactor, wind);
pET = Letp / latH;
aET = 0;
//converting mm to litres
pET = pET * area;
//aggregation to monthly values
if (this.time != null) {
if (this.tempRes.getValue().equals("m")) {
int daysInMonth = this.time.getActualMaximum(time.DATE);
pET = pET * daysInMonth;
}
}
//avoiding negative potETPs
if (pET < 0) {
pET = 0;
}
this.potET.setValue(pET*et_cal.getValue());
this.actET.setValue(aET);
if (dataCaching.getValue() == 0) {
writer.writeDouble(pET*et_cal.getValue());
}
}
}
7. O procedimento de limpeza (cleanup) é realizado no final de uma execução de modelo.
public void cleanup() throws IOException {
if (dataCaching.getValue() == 0) {
writer.flush();
writer.close();
} else if (dataCaching.getValue() == 1) {
reader.close();
}
}
8. Procedimentos particulares e funções. Estes só estão disponíveis dentro do componente do processo.
private double calcPM(double ds, double netRad, double G, double pa, double CP, double est, double ea, double psy, double tempFactor, double wind){
double fu = (0.27 + 0.2333 * wind);
double Letp = (ds * (netRad - G) + (pa * CP * (est - ea) * fu)) / (ds + psy);
return Letp;
}
private double calc_groundHeatFlux(double netRad) {
double g = 0.1 * netRad;
return g;
}
9. Fim do componente de processo.
}
Desenvolvimento e Implementacao de componentes de contexto JAMS
Integração de novos Componentes de Processo nas Bibliotecas JAMS ou J2000
Para adicionar o seu componente de processo gerado aos componentes JAMS ou J2000 existentes, crie um novo *. jar do projeto, onde o componente está localizado. Para tal clique com o botão direito do mouse sobre o projeto e selecione o item Build and Clean. Agora integre este *. jar como uma biblioteca, onde o seu novo componente poderá ser encontrado.
Integração e Teste de Novos Componentes (de Contexto)
Para integrar novos componentes (de contexto) a modelos existentes ou para usá-los em novos modelos, a ferramenta JUICE está disponível para a concepção de modelos. Na seção 1.2 Aplicação do JUICE para o desenvolvimento e a configuração de um modelo no Tutorial Usuários Avançados todos os passos para a integração de componentes são explicados. Usando o JUICE, o modelo pode ser iniciado e, consequentemente, os novos componentes podem ser testados.
Depuração e Perfilamento de Modelos em JAMS
Depuração
Para compreender o funcionamento dos componentes (JAMS/J2000) já criados e existentes e para facilitar a pesquisa de erros no processo de desenvolvimento, está à sua disposição a possibilidade da depuração. É possível selecionar as posições no código-fonte usando pontos de parada, onde o compilador deve parar a execução do modelo. Torna-se assim possível visualizar os valores das variáveis designadas no momento. Além disso, o funcionamento do componente desenvolvido ou existente pode ser traçado linha por linha. Antes de iniciar o modo de depuração do modelo, é preciso definir pontos de parada nas posições que lhe são interessantes. Para fazê-lo, clique no ponto vermelho da barra de menu e depois na posição no código-fonte. Na imagem seguinte, dois pontos de parada foram estabelecidos:
Se o componente tem um procedimento principal (Main-Procedure), é possível iniciar a depuração diretamente. Se o componente faz parte de um modelo complexo, já é necessário depurar o modelo inteiro. Neste caso, clique com o botão direito do mouse sobre o projeto que deve ser iniciado (o projeto que contém o componente) e selecione debug.
A execução do modelo será parada na posição selecionada. Na janela inferior é possível ver a atual alocação de variáveis do modelo. Na janela do lado esquerdo superior, é possível ver a posição no código-fonte.
Agora pode-se compreender o funcionamento do código-fonte passo a passo. Para isso, as seguintes funções estão disponíveis, as quais podem ser encontradas na barra de menu do Netbeans sob o item Debug ou, parte delas, diretamente na barra de menu:
- Finish Debug Session - encerra o modo de depuração
- Continue - vai para o próximo ponto de parada
- Step Over - vai para a próxima indicação
- Step Into - entra na indicação, se possível. Caso não, vai para a próxima
- Step Out
As funções Step Over e Step Into podem ser usados para traçar e compreender o funcionamento do código-fonte passo a passo. A linha com sombra verde marca a posição atual que está sendo analisada.
Ao clicar no botão Continue pode-se ir para o próximo ponto de parada (linha com sombra vermelha).
Perfililamento no Netbeans
O Netbeans oferece uma possibilidade para compreender a execução dos modelos, ou seja, que parte do modelo requer que quantidade de tempo. Desta forma, implementações que consomem muito tempo podem ser identificadas.
Para isso, clique com o botão direito do mouse sobre o projeto que deve ser analisado. Selecione a classe principal no item Run em Propriedades onde o perfilamento deve ser executado.
Agora selecione o item Profiling (Perfilamento).
A seguinte janela irá se abrir. Agora pode-se escolher entre analisar o código-fonte por completo ou apenas suas partes. As seguintes opções estão disponíveis para a filtragem:
- Profile all classes (Perfilar todas as classes)
- Profile only project classes (Perfilar somente classes de projetos)
- Exclude Java core classes (Excluir classes centrais de Java)
- Quick Filter (Filtragem rápida)
Clique em run.
A análise de execução está sendo realizada. A seguinte janela irá aparecer.
O resultado da análise é mostrado no Netbeans. Na janela da esquerda, são exibidas informações gerais sobre o seu perfil. Na janela superior direita são exibidos os tempos de execução das funções individuais dentro da classe principal selecionada.
























