: : www.mundoj.com.br : : Na maioria das vezes, um software científico necessita de alto desempenho em operações aritméticas e, realmente, comparada a algumas linguagens de baixo nível, Java tem um desempenho duvidoso neste viés. Porém, isso não inviabiliza o desenvolvimento científico com Java. Existem soluções para este problema, e este artigo vem demonstrar uma que diminui o tempo de desenvolvimento de um software que precise resolver (de forma extremamente confiável) expressões aritméticas e pode até diminuir o tempo de execução destas operações. Fernando Paim Lima ([email protected]): Graduado em Ciência da Computação (2005), especialista em Banco de Dados (2006). Atualmente é mestrando em Engenharia de Sistemas e professor do Instituto Federal de Educação, Ciência e Tecnologia – Minas Gerais. Tem experiência na área de Ciência da Computação, com ênfase em Lógica Fuzzy, Redes Neurais, Programação Web, Programação Comercial, Banco de Dados, Interoperabilidade entre plataformas e Visão Computacional. Java + Máxima Alternativa para Desenvolvimento Científico Integrando Java à ferramenta algébrica “Maxima”. xistem algumas informações equivocadas em algumas mídias de comunicação deixando a entender que Java não pode ser útil a cientistas que trabalham com uma “massa” muito grande de dados e que precisem de várias operações aritméticas. De fato, Java não tem a mesma performance que linguagens de baixo nível como C [7][8] ou a facilidade de programação de Fortran se tratando de operações aritméticas[1]. Talvez seja por causa destes motivos que existam várias ferramentas algébricas desenvolvidas em Fortran, C ou Lisp, e pouquíssimas em Java. 62 Assim o maior “preconceito” com o desenvolvimento Java (por parte de desenvolvedores da área científica) é essa disparidade no desempenho entre Java x Linguagens de Baixo Nível se tratando de operações aritméticas. Este artigo vem propor uma forma alternativa de solução de expressões aritméticas para softwares desenvolvidos na linguagem de programação Java, utilizando um driver de conexão com o pacote algébrico Maxima de forma a diminuir o tempo de desenvolvimento, e podendo até diminuir o tempo de execução na solução de expressões aritméticas com altíssima confiabilidade nos resultados das expressões aritméticas. Ciência e Java Quem acha que Java não é presente no mundo científico precisa se informar melhor, pois existem várias ferramentas científicas que possuem módulos em Java ou que auxiliam a comunidade de desenvolvimento científico Java, como, por exemplo: - Maple[6]: pacote algébrico proprietário que tem interface gráfica em Java; - Oculus[5]: a representação gráfica interativa de dados financeiros e eventos, também tem uma implementação Java; - JScience[2]: pacote Java científico com suporte para várias áreas do conhecimento: matemática, física, sociologia, biologia, astronomia, economia etc.; - Joone[14]: pacote com ferramentas para se trabalhar com redes neurais escrito em Java; - jFuzzyLogic[15]: pacote de ferramentas para se trabalhar com Lógica Fuzzy escrito em Java; -JEP Java: Math Expression Parser[19]: pacote Java para analisar e avaliar expressões matemáticas. Além destes exemplos, existem vários indícios de que a utilização de Java no meio científico vem aumentando, como, por exemplo, a disponibilização de temas para dissertações em programas de mestrado[4]. Recursos aritméticos da linguagem Java Além dos operadores aritméticos clássicos (+, -, *, /, %), Java possui a classe Math que é um recurso muito utilizado para operações aritméticas. A classe possui vários métodos úteis como os métodos para potenciação, radiciação, além de métodos trigonométricos como seno, cosseno etc. Como exemplo de utilização da classe Math, o código Java abaixo imprime na tela seno de 45 graus somado ao valor do cosseno de 45 graus, matematicamente sen(45)+cos(45) System.out.println( Math.sin(45) + Math.cos(45) ); Recursos numéricos da linguagem Java Um problema da linguagem quase totalmente resolvido foi a falta de aplicação efetiva de grande parte de regras do padrão IEEE 754 para ponto flutuante nas primeiras JVMs. Nas primeiras versões da JVM foram escolhidas duas formas representativas de ponto flutuante na linguagem, os tipos de dados float e double. O tipo float trabalha com 4 bits de armazenamento e possui 23 dígitos de precisão, já o tipo double trabalha com 8 bytes de armazenamento, e tem 52 dígitos binários de precisão[3]. Foi observado em JVMs anteriores a 1.2 que havia um problema com os valores-resultados de operações aritméticas que exigiam vários cálculos com números flutuantes em uma operação, e por isso também se exigia grande precisão numérica. Se houvesse algum overflow ou underflow durante tais operações, sempre era retornado um número válido, acarretando erros numéricos[11]. A partir da JVM 1.2, foi disponibilizado o recurso Strict Float Point que restringe operações com valores dos tipos foat e double a serem adequadas à grande parte das regras do padrão IEEE 754[12] para ponto flutuante[9][11], de forma a corrigir o problema de se retornar sempre um número válido mesmo ocorrendo overflow ou underflow durante as operações aritméticas. Segundo Thomas Wang (2000)[3], o padrão IEEE 754 prevê a definição de ponto flutuante infinitos, infinitos negativo, zero negativo, e NaN (não um número). Para entender melhor esse padrão, verifique a referência [12] Mas, para não haver problemas de execução de softwares Java em JVMs anteriores à 1.2, existe o modificador strictfp que atua na compilação Java (geração de byte codes) obrigando que durante sua execução, seja adotada grande parte das regras do padrão IEEE 754 para pontos flutuantes, mesmo que a aplicação seja executada em JVMs anteriores a 1.2. Abaixo é demonstrado um exemplo de utilização do modificador em um método: public strictfp void teste() { //... } Também podemos utilizar este modificador para toda uma classe: public strictfp class Teste{ //... } Deve se observar que mesmo que se tenha um hardware com capacidade maior de armazenamento e processamento aritmético, este modificador limita tais recursos extra de hardware[1] (para saber mais sobre este limite, consultar também [18]). As principais diferenças entre a aritmética de ponto flutuante apoiado pela máquina virtual Java e do padrão IEEE 754 segundo LINDHOLM, T., et.al.(1999) [13] são os seguintes: - As operações de ponto flutuante da máquina virtual Java não lançam exceções em condições excepcionais de operação inválida, divisão por zero, overflow, underflow, ou inexata. A máquina virtual Java não trabalha com sinalização (positivo, negativo) para valores NaN. - Nas operações de arredondamento da máquina virtual Java, os resultados inexatos são arredondados para o valor mais próximo representável. -Na conversão de um tipo ponto flutuante para inteiro, os valores decimais são arredondados para zero. A máquina virtual Java não dá qualquer meio para mudar o modo deste arredondamento. - A máquina virtual Java não suporta, exatamente como o padrão IEEE 754, os formatos de: ponto flutuante double estendido ou float estendido, com apenas algumas exceções. Para mais informações sobre tais diferenças, consulte a referência [13]. Considerações entre Ciência e Java Mesmo com tantos exemplos e recursos aritméticos, em comparação com linguagens de baixo nível, são raros os softwares científicos Java que objetivam ou que utilizam de operações aritméticas na própria linguagem. Java não possui o mesmo desempenho que algumas linguagens de baixo nível se tratando de operações 63 : : www.mundoj.com.br : : aritméticas [10], além de não obedecer totalmente ao padrão IEEE 754[13]. No intuito de se criar uma alternativa a este problema, é demonstrada na continuação deste texto, uma forma de realizar todo o processamento aritmético de um software Java em um pacote algébrico construído em Lisp, o Maxima melhorando a performance aritmética e diminuindo drasticamente o tempo de desenvolvimento. Ferramenta Algébrica Maxima Maxima é um sistema de álgebra computacional implementado em Lisp para a manipulação de expressões simbólicas e numéricas, séries de Taylor, transformadas de Laplace, equações diferenciais ordinárias, sistemas de equações lineares, polinômios etc.[16] Segundo GAT, E. (2000)[17], Lisp é muito mais indicada para operações aritméticas em termos de desempenho que as Linguagens C++ e Java. Para utilizar o Maxima, basta baixar o software no site do fabricante [16], instalá-lo, executar seu console e digitar a expressão aritmética que quiser dentro de uma função float(); e pressionar a tecla enter que será retornado o resultado em números reais e, se for o caso, em números imaginários. Veja o exemplo abaixo, ele retorna o resultado da operação “sen(45)+cos(45)”: Pacote Algébrico Maxima Software Desenvolvido maxidriver.jar Figura 2. Utilização do driver “maximadriver.jar”. Por enquanto, existem duas formas de conexão, pela classe ConnectionMaxima e pela ConnectionMaximaGenerica. Utilizando a conexão com a classe ConnectionMaxima, ao instanciar o objeto, já é estabelecida a conexão através de streams, a partir daí, pode-se executar quantos comandos (funções aritméticas) forem necessários, pois o software Máxima estará “aberto” internamente em seu software Java. Obs.: foram realizados testes com sucesso em ambientes Windows, mas ainda apresenta instabilidade em ambientes Linux. Utilizando a conexão com a classe ConnectionMaximaGenerica não é aberto um canal de streams na instância do objeto da classe, esse canal é aberto junto com o envio do comando (função aritmética) e fechado logo após o recebimento da resposta do Maxima. Obs.: com a classe ConnectionMaximaGenerica foram realizados testes com sucesso em ambientes Windows e Linux. Forma prática Abaixo segue a forma de utilização da classe ConnectionMaxima, analogamente à ConnectionMaximaGenerica.Primeiramente se adiciona o driver às bibliotecas do seu software. Se sua IDE for o NetBeans, basta você selecionar o projeto de seu software na aba projetos, clicar com o botão direito em cima no nome do seu projeto, clicar na opção propriedades, selecionar a opção bibliotecas, a partir daí adicionar o arquivo maximadriver.jar às bibliotecas do seu projeto. Figura 1. Console xmaxima. Figura 3. Biblioteca “maximadriver.jar”. O Maxima também possui várias outras funcionalidades em relação a cálculo diferencial e integral. Materiais e métodos Está sendo construído (primeiramente pelo autor deste texto) um driver de conexão entre Java e a ferramenta algébrica Maxima (protótipo disponível para download no site da revista) que a princípio será disponibilizado para o uso gratuito, e posteriormente será disponibilizado de forma livre para que possa ser melhorado. Esse driver é indispensável para o propósito deste artigo. Funcionamento do driver Modelo de funcionamento do driver: 64 Posteriormente, é feita a instância de um objeto da classe ConnectionMaxima passando a URL do arquivo de execução do software “Maxima”: ConnectionMaxima ece = ConnectionMaxima.getInstance( "C:/Program Files/Maxima-5.21.1/bin/maxima.bat" ); A partir daí, pode-se executar comandos (funções aritméticas) e obter suas respostas: String expressao = JoptionPane.showInputDialog("Digite a expressão"); ece.enviaComando(expressao + ";\n"); Software exemplo No site da revista, existe para download, um exemplo prático de utilização do driver proposto neste artigo. Em execução, sua primeira tela (JOptionPane) simplesmente pede que seja digitada a URL do arquivo “maxima.bat” em seu diretório raiz. Figura 4. Software Exemplo – tela 1. Caso o usuário clique em OK, em seguida irá aparecer uma tela em que o usuário deve digitar qualquer expressão aritmética. Nota-se que: - para a fórmula da densidade populacional, todas as tecnologias retornaram o mesmo resultado (correto), sendo que a ordem das tecnologias para a velocidade de processamento é a seguinte: Java + Classe Math, Java + JEP e Java + Máxima; - para a fórmula da energia livre, a tecnologia Java + JEP retornou o resultado errado e a ordem de velocidade de processamento continua a mesma; - para a fórmula da entropia, somente Java + Maxima retornou o resultado de forma correta, pois a tecnologia Java + JEP retornou um resultado errado, e Java + Classe Math retornou NaN (provavelmente houve underflow ou overflow). Obs1: os resultados obtidos em um computador com o processador Intel Core 2 Duo T65000 2.1GHz, e memória RAM de 3GB, no sistema operacional Windows Vista Home Premium 32 bis Service Pack 2. Obs2: as fórmulas da entropia, densidade populacional e energia livre estão disponíveis na classe TesteTecnologias.java no projeto exemplo no site da revista. Considerações finais Figura 4. Software exemplo – tela 2. E finalmente, após o usuário clicar em no botão OK, irá aparecer o resultado da operação aritmética calculado pelo pacote algébrico Máxima. Software exemplo – tela 3. Comparações entre Java+Maxima, Java+JEP e Java+Classe Math Assim como algumas linguagens de alto nível, Java possui limitações quanto a desempenho a respeito de operações aritméticas, mas isso não inviabiliza a utilização de Java na ciência, basta escolher a melhor forma de se trabalhar com a linguagem. Utilizando o driver proposto, de fato pode haver certa perda de performance por causa da troca de informações entre as duas aplicações, mas há um ganho em confiabilidade de resultados, pois, o Maxima é uma ferramenta matemática de alta confiabilidade usada no mundo inteiro por cientistas das mais diversificadas áreas do conhecimento (engenharias, física etc.) e também há um ganho muito grande no tempo de desenvolvimento, pois o programador não precisa fazer módulos (sintáticos, semânticos e aritméticos) necessários para solução de expressões aritméticas• Referências Java+Maxima Java+JEP Java+Math Densidade Populacional Resultado: 7.328457504199093, Duração: 2 milissegundos Resultado: 7.328457504199093, Duração: 0 milissegundos Resultado: 7.328457504199093, Duração: 0 milissegundos Energia Livre Resultado: 7.389237985167935, Duração: 5 milissegundos Resultado: 2.3835706919459616, Duração: 2 milissegundos Resultado: 7.389237985167935, Duração: 0 milissegundos Entropia Resultado: 1.091432967835645 Duração: 24 milissegundos Resultado: 0.9992561797106484, Duração: 33 milissegundos Resultado: NaN, Duração: 0 milissegundos Junto ao exemplo de utilização do drivermaxima.jar, no site da revista existe uma classe que realiza testes simples da tecnologia apresentada neste trabalho: Java+Maxima e de outras tecnologias: Java + JEP e Java com a classe Math. Tais testes foram realizados de forma a verificar a confiabilidade das tecnologias visando os resultados das expressões aritméticas e o tempo de duração que cada tecnologia executou tal processamento. [1] http://www.developer.com/java/ent/article.php/631201/Java-as-a-ScientificProgramming-Language-Part-1-More-Issues-for-Scientific-Programming-in-Java. htm, Acessado em 02/07/2010 [2] http://jscience.org/, Acessado em 02/07/2010 [3] http://www.concentric.net/~Ttwang/tech/javafloat.htm, Acessado em 02/07/2010 [4] http://www.peb.ufrj.br/noticias/2010-05-26-RelacaoTemas2010.pdf, Acessado em 02/07/2010 [5] http://www.oculusinfo.com, Acessado em 02/07/2010 [6] http://www.maplesoft.com/, Acessado em 02/07/2010 [7] http://www.sbmac.org.br/eventos/cnmac/xxxi_cnmac/PDF/114.pdf, Acessado em 02/07/2010 [8] http://www.ukhec.ac.uk/publications/tw/hpcjava.pdf, Acessado em 02/07/2010 [9] http://www.roseindia.net/help/java/s/strictfp.shtml, Acessado em 02/07/2010 [10] http://www.developer.com/java/article.php/3856906/Java-vs-C-The-Performance-Showdown.htm, Acessado em 02/07/2010 [11] http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc. html#24465, Acessado em 02/07/2010 [12] IEEE, "ANSI/IEEE Std 754-1985, An American National Standard IEEE Standard for Binary Floating-Point Arithmetic", (1985) [13] LINDHOLM, T., YELLIN, F., The Java Virtual Machine Specification, Second Edition, Sun Microsystems, 1999. [14] http://sourceforge.net/projects/joone/, Acessado em 02/07/2010 [15] http://jfuzzylogic.sourceforge.net/html/index.html, Acessado em 02/07/2010 [16] http://maxima.sourceforge.net/, Acessado em 02/07/2010 [17] GAT, E. Lisp as an alternative to Java. Intelligence 11(4), pag. 21-24, 2000. [18] http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf, Acessado 07/10/2010 [19] http://sourceforge.net/projects/jep/ 65