Compatibilidade e Performance do Mono - Dúvidas e Discussão de Programação - Portugal-a-Programar
Compatibilidade e Performance do Mono
Por pedrotuga, 11 de Janeiro de 2009 em Dúvidas e Discussão de Programação
Em teoria é correria no mono, na prática, a não ser que seja uma aplicação muito simples que só recorra a bibliotecas básicas, é preciso quase sempre recompailar e na maior parte das vezes arranjar workarounds.
Embora esteja a fugir ao tópico, tenho de refutar a afirmação. Até ao à versão 2.0 do .net tudo costuma funcionar sem alterações. No 3.5 há alguns pormenores que podem não funcionar, o suporte ainda não é completo.
A mono tem um aplicativo para converter, eu ainda não estou muito convencido é na performance do mono :S
A ultima vez que usei aplicações .NET com mono foi no OpenSuse eles usam muito e a performance pareceu-me muito afectada, mas não sei como anda agora :S
Nem em Ubuntu nem em Windows noto qualquer diferença de performance, funciona do mesmo modo que na plataforma .net.
Quanto à aplicação de conversão, é mais uma aplicação de verificação e conselhos de conversão, não converte automaticamente por ti, apenas ajuda a identifica possíveis incompatibilidades... mas é impressão minha ou já nos devíamos bastante do tópico?
A mono tem um aplicativo para converter, eu ainda não estou muito convencido é na performance do mono
Mono não é tão rápido como a plataforma .NET, mas mesmo assim está quase a nível do Java, em termos de performance, o que é normalmente 2-3x mais lento que código em C/C++. Eu diria que é aceitável. Acho que a malta do Mono tem nos planos das próximos versões melhorias de performance, por isso ainda deve ficar mais rápido no futuro.
E muito melhor para fazer aplicações para desktop do que o Python, que é em norma 20-30x mais lento que código em C/C++.
2 a 3 vezes?! Ena que números.
Pelo menos desde 95 que chamas a métodos em Java são tão rápidos como em C++ e desde 2000 que as velocidades são equivalentes. Embora equivalentes não seja o mesmo que iguais, há coisas em Java que são mais rápidas que em C ou C++ e vice-versa. Tal como há idiomas de C mais rápidos que outros. Em resumo, a velocidade de Java está equivalente à de C/C++ e não 2 a 3 vezes mais lento.
O mesmo se dirá do .net e de Mono. No caso de Mono, a correr em Windows, não noto qualquer diferença a executar aplicações de .net para as quais a compatibilidade é total.
A performance de Java/C# não é igual à de C/C++. Nem de longe.
Pode ser semelhante em alguns casos, mas eu disse no geral. 2/3 vezes mais lenta que C/C++ não me parece nada mau, uma vez que a linguagem é interpretada e tem de ser compilada para código máquina em tempo de execução.
Mas isto digo eu, que nunca fiz benchmarks. E todos os que vi parecem confirmar as minhas teorias.
Não vou entrar nessas discussões, até porque existem vários estudos feitos, alguns com mais de 10 anos que indicam velocidades semelhantes.
Mas posso perguntar se, como dizes, Java é compilado para código nativo, qual a diferença na compilação para que dois códigos nativos corram com velocidades na ordem das 2 ou 3 vezes de diferença.
A velocidade é uma coisa muito relativa. Pode não querer dizer nada, uma aplicação pode usar a tecnologia mais rápida de todas mas pode acabar por ser menos responsiva por causa de bloats e afins.
Sempre fui muito céptico em relação a isso do java ser tão rápido como o C++. O que eu sei da minha experiencia de utilizador é que as aplicações Java são de um modo geral mais pesadas que as que são escritas em C++.
Mas isso provavelmente terá a ver com a filosofia da aplicação.
As aplicações em python, pelo menos as que conheço e uso, são geralmente simples e leves e não são lambareiras em termos de memória. Moral da história, o python com toda a sua lentidão toda acaba por não ter problemas com a velocidade porque os programadores de python usam um paradigma diferente.
Quanto às do mono... assim que me lembro uso o tomboy e o beagle, até agora a experiência tem sido suave sem 'empancamentos', mas tambem nunca experimentei em computadores mais lentos.
Mas indo ao cerne da questão, que aplicações é que vocês usam onde a velocidade de processamento tenha uma importancia central? Para mim, tirando o ffmpeg, a velocdade de processamento é coisa que não interfere com a minha experiencia de utilização. É tudo point-and-click em funcionalidades simples ou então comandos manuais que respondem imediatamente.
Sempre fui muito céptico em relação a isso do java ser tão rápido como o C++.
Tipicamente quando se fala em velocidade o Java, e as linguagens que correm em .net/Mono, são sempre consideradas mais lentas, acho que isso se deve a muita "desinformação", se Java é compilado nativamente e C é compilado nativamente, então são dois códigos compilados nativamente para a plataforma a executar, porque é que um será mais lento que outro? Seria o mesmo que dizer em duas aplicações feitas em C iguais, uma tem uma velocidade 2 vezes superior à outra. Simplesmente não tem muita lógica.
Claro que há coisas em Java que são mais lentas, tal como há coisas em C++ que são mais lentas, tal como há variantes de C++ que são mais lentas que outras. Agora chegar ao ponto de dizer 2 a 3 vezes, quando à mais de 10 anos que as tecnologias andam a par é algo que apenas continua com a dita "desinformação".
Não gosto de discutir isso de velocidades, é algo bastante subjectivo e cuja comparação exige muito esforço e conhecimento das tecnologias envolvidas. Poucos são os resultados de bechmarks que aparecem nos resultados do Google que sejam feitos correctamente.
A performance é algo que resulta de vários factores, para mim, performance inclui mais que velocidade marcada na máquina, inclui tempo de desenvolvimento, custo de desenvolvimento, velocidade de processamento, tempo de manutenção, tempo que o utilizador tem de esperar, enfim, um conjunto de factores bastante mais elevado que simples velocidade medida de formas muitas vezes dúbias.
A execução de código nativo Java e de código nativo C++ é feita à mesma velocidade, é código compilado nativamente nos dois casos. Agora, como o pedrotuga disse, onde é que a maioria dos utilizadores verifica isso? Onde é que essa velocidade se sente?
Pessoalmente já nem penso em usar C ou C++ para desenvolver aplicações, ganho muito pouco ou aliás, nada em relação ao uso de Java, C#, python ou outras linguagens onde desenvolvo mais rapidamente. Há coisas que linguagens como C# e Java não serão tão simples de usar ou tão indicadas mas isso são casos muito especificos, na maioria das situações ganha-se pouco no uso de C ou de C++ e o utilizador não nota a diferença.
Agora, pegando no Java, que é onde tenho tido mais experiência, tanto em desenvolver como em ver aplicações desenvolvidas, existe muito má programação na linguagem. Existem muitos casos onde são feitas autênticas atrocidades no uso da linguagem que não passam de transferências directas do que os programadores estavam habituados a fazer em C, C++, VB ou até Delphi, que em Java simplesmente dão mau resultado. É necessário ver que cada tecnologia tem as suas caracteristicas que necessitam ser respeitadas, se estamos a programar usando Swing então temos de ter atenção às particularidades do Swing, que diferem da forma como o wxWidgets funciona ou como funcionam os componentes do Delphi. Tal como não se deverá ir para C++ usando o que se faz em Java, não se deve trazer para o Java as formas de programar de C++.
A nível de compatibilidades do Mono e performance, pela experiência que tenho, está bastante boa, e nos últimos tempos cada vez melhor. Uso tanto em Windows como em Ubuntu e tenho o meu IDE e parte do sistema configurado para correr aplicações no Mono em vez de usar a plataforma .Net. Algumas aplicações feitas aqui no P@P por membros que desenvolveram em .net correm sem qualquer problema em Mono, à mesma velocidade.
Mesmo esta velocidade é complicada de medir, existem vários factores que dependem do SO e das configurações usadas, e em Linux dependem bastante do software que está por base, especialmente componentes gráficas e de som.
Mas enfim, não posso falar mais do que por experiência, e a minha será certamente muito diferente da vossa. Para mim, não há diferenças de velocidade e a compatibilidade está muito boa.
Quanto a aplicações que necessitem de ser muito rápidas, cada vez desenvolvo menos. Cada vez existem menos aplicações para as quais uma velocidade crua seja necessária.
O problema é que o Java não é compilado para código máquina, mas sim para bytecode, que ainda vai ser interpretado..
Eu acredito que em projectos de dimensões maiores ou GUI que as diferenças se comecem a esbater, mas falando daquilo a que estou habituado que são os concursos de programação, Java é bastante mais lento que C ou C++.
PS: Sim, eu sei que Java pode ser compilado para código máquina com GCJ.
Bytecode não código nativo para a máquina de java? De qualquer das formas é rigorosamente o mesmo grau de abstração que o .net.
A expressão 'linguagem interpretada' refere-se mais ao ciclo de desenvolvimento, tendo o programador que compilar ou não o seu código. O python, perl, php tambem acabam por ser compilados. O caso do python pelo menos não é muito diferente do java, a maior diferença é mesmo o facto de não ser preciso compilar manualmente.
Knitter, era giro que fosse como dizes, mas na realidade qualquer linguagem interpretada/JIT é mais lenta que um programa equivalente em C/C++.
Repara, Java tem de compilar o bytecode para código máquina em tempo real, um overhead que não existe em C/C++ porque já foram compiladas de antemão. Além disso ainda tem de fazer pausas recorrentes devido ao garbage collector. E não esquecer que não transforma todo o código da aplicação em código máquina, apenas as partes que são executadas mais frequentemente (daí o nome "HotSpot compiler").
Em teoria, uma linguagem que compile em tempo de execução pode realmente ser mais rápida que uma linguagem interpretada em programas de longo curso, pois pode usar a informação de qual código é executado mais vezes para optimizar o código para o caso concreto da execução, mas ainda não se viu isso em termos práticos.
Acredito que para a maioria das aplicações isso não faça qualquer diferença a longo curso, pois como disseste não interessa apenas o tempo de execução, mas também muitos outros factores como tempo de desenvolvimento, custo da aplicação, manutenção, entre outros... mas convém estar consciente que essa diferença realmente existe.
Bem, para mim este é o ponto essencial. Estar a discutir velocidade de execução apenas, é algo um pouco fútil. 99% das aplicações perdem mais tempo em input/output (dispositivos externos, utilizador, etc) para que a diferença de velocidade importe.
Em relações a comparações, segundo o language shootout (e isso vale o que vale, praticamente nada), dá para ver que Java é cerca de de 1.7 vezes mais lento que C++. Mas se olharmos para a memória constatamos que consome cerca de 11 vezes mais. Isto pode significar duas coisas, como são testes curtos,o GC não chega a entrar em acção, ou então por natureza Java consome muita memória. Eu penso que seja mais provável a segunda hipótese, e aí é que está o verdadeiro problema. Quando muitas vezes vê se os utilizadores a queixarem-se que o programa de Java é pesado e lento, muito provavelmente é em Windows (onde há uma má gestão de memória do SO) e que essas lentidões acontece quando se está a libertar memória (GC) ou a tentar obter mais memória. De salientar que quando o GC entra em acção todo o programa pára.
Como o Triton disse e bem, Java é interpretada (refiro-me ao standard), e como tal vai ser mais lenta que se for compilado directamente para código nativo. Mas depois tem o HotSpot como o Triton também referiu, apesar de que ele diz que ainda não viu exemplos práticos. É falso, já foi demonstrado inumeras vezes que o HotSpot é uma mais valia, e quem anda por este mundo à uns anos facilmente verifica a evolução que as VMs têm dado. Acredito que no futuro é perfeitamente possível uma linguagem compilada para bytecode e depois interpretada, (como é o caso de Java, C#, etc) seja mais rápida que uma linguagem compilada de forma tradicional. De salientar que será sempre complicado que Java seja mais rápido que C++, maior riqueza da linguagem trás uma degradação de performance, exemplo GC, por muito bom que seja, nunca será melhor que uma optimização manual de libertação de recursos como é possível no C++.
Aliás acredito que o futuro seja mesmo cada vez mais uso de VMs, a popularidade de linguagens indica isso, Java, C#, como a popularização de mais VMs, LLVM , Parrot.
Bem mas esta thread é para se falar no Mono e não no Java.
Em relações de performances não sei, como no trabalho é usado apenas Windows uso exclusivamente .Net. Mas Mono tem uma cena porreira que é o compile ahead-of-time que até apareceu nas noticias à pouco tempo.
http://arstechnica.com/news.ars/post/20090108-open-source-mono-framework-brings-c-to-iphone-and-wii.html
Estamos a entrar em discussões um pouco parvas, as avaliações de 95, à quase 15 anos, indicam uma velocidade de execução de métodos de Java igual à de métodos de C++. Várias melhorias foram introduzidas desde então. A questão de Java ou outra linguagem que use o mesmo sistema ser mais lenta que C++ já não se coloca há alguns anos.
Essas são ideias que, infelizmente, perduram, se fizeres um bom teste de avaliação, a conclusão que chegas é que a velocidade é a mesma. Claro que existirão diferenças em alguns pontos, tal como existem mesmo em diferentes implementações de C++, mas são diferenças negligenciáveis.
O código pode ser compilado em execução, mas é compilado uma única vez, se estamos a comparar a velocidade então comparamos a velocidade quando ambos estão compilados, senão estamos a comparar coisas diferentes. Ou então compara-se incluindo o tempo de compilação da aplicação em C++.
Mas o que é que isto interessa na verdade? Não estamos em 1990 com sistemas de baixos recursos, actualmente até um telemóvel tem mais capacidade de processamento que um P3. No fundo é discutir o sexo dos anjos, o que acho importante é que se pare com a perpetuação de que Java ou C# são linguagens mais lentas apenas porque são uma tecnologia diferente do C++. E mesmo dizer que são 2 a 3 vezes mais lentas é algo errado, podia ser assim antes do Java 1.4, mas actualmente uma afirmação dessas não faz sentido e é um erro.
Quanto a consumir mais memória, aí, pelo que tenho visto, entra muito da culpa do programador. Por omissão a máquina virtual usá entre 32MB a 64MB que reserva imediatamente, mesmo que só esteja a usar efectivamente 1KB. E essa diferença irá sempre ser feita, isto é, existirá sempre mais memória reservada que a efectivamente necessária. Mas existe também muito má gestão de memória por parte dos programadores, o GC ajuda bastante e é um ponto importante, mas o programador tem de trabalhar sem pensar no GC, até porque não o pode controlar nem esperar que ele actue quando precisa.
A última que vi foi do Vuze, antigo Azureus, que consome memória em coisas completamente absurdas, basta fazer um profilling da memória para ver muito má gestão de memória no sistema.
Repara, Java tem de compilar o bytecode para código máquina em tempo real
Penso estares a fazer uma confusão aqui.
Os detalhes do funcionamento das máquinas de Java ultrapassam os limites do meu conhecimento e para dizer a verdade do meu interesse, mas é uma máquina virtual, não é um compilador. O bytecode a que te referes é código máquina para todos os efeitos, a única diferença é que corre numa máquina virtual. "Compilar bytecode para código máquina" é uma expressão errónea pelo menos neste caso. A máquina virtual é uma implementação de um processador (na verdade de uma máquina completa, daí o nome) num sistema operativo. Recebe instruções (bytecode) e executa-as, isto não é propriamente compilar código. Não há parsing absolutamente nenhum. A única coisa que há a comparar é mesmo a efficiencia de uma máquina virtual comparada com a de uma máquina física. Obviamente a máquina virtual não pode ser mais eficiente que a máquina onde o sistema operativo onde corre está. Mas ha outros aspectos a ter em conta, por exemplo, se tu e eu instalarmos o JVM da sun, supostamente as nossas máquinas de java são iguais, e ao corrermos uma aplicação, o mais provavel é esta ter sido compilada numa máquina igual à nossa. Por outro lado, se eu fizer o download de uma aplicação escrita em C++ e compilada, vou estar a fazer download de uma aplicação compilada para correr um 386, eu e todos os outros utilizadores de computadores com a mesma arquitectura que o meu. Ou seja, foi compilada para correr numa miríade de máquinas diferentes, logo não será propriamente optimizada para o meu sistema. Claro que posso sempre compila-la eu no meu computador...
O que sei e que me parece relevante é: a máquina virtual de java da sun, que é a que eu uso, é aparentemente pesada. Os interpretadores de bytecode de python e de perl são leves assim como o interpretador de PHP por exemplo. O CLI ou lá como se chama a máquina que o mono traz.. .não sei ainda não tenho dados suficientes.
EDIT: Grrr.. eu a escrever esta mensagem e o knitter o betovsky deitam os melhores e mais informativos posts deste tópico na minha opinião.
hurray for VMs! Tambem digamos, era tempo de deixar incompatibilidades para trás.
Mas depois tem o HotSpot como o Triton também referiu, apesar de que ele diz que ainda não viu exemplos práticos. É falso, já foi demonstrado inumeras vezes que o HotSpot é uma mais valia, e quem anda por este mundo à uns anos facilmente verifica a evolução que as VMs têm dado.
Se disse que ainda não tinha visto exemplos práticos do HotStop (não me apetece reler o meu post) enganei-me. Ajuda no aumento da performance, pois compila o código executado mais frequentemente para código máquina.
Estamos a entrar em discussões um pouco parvas, as avaliações de 95, à quase 15 anos, indicam uma velocidade de execução de métodos de Java igual à de métodos de C++.
Estudos feitos em 95 não são muito relevantes. Ambas as tecnologias evoluiram bastante até hoje. Mesmo que a velocidade de execução de métodos (não sei bem o que queres dizer com isto) do Java na altura fosse semelhante ao C++, hoje em dia pode muito bem ser diferente. Conhecem-se muitas novas técnicas de optimização de código, os compiladores de C++ estão muito mais maduros, e consequentemente geram código mais rápido.
O que interessa é o resultado no final. Se eu começo 2 programas ao mesmo tempo, o tempo que conta é o tempo desde a criação do processo até ter obtido o resultado. Se o Java precisa de compilar em runtime, isso não deve ter sido em conta. É um pormenor interno da tecnologia.
Já agora, um grande problema que se estão a esquecer, é que mesmo que o JIT do Java possa gerar o mesmo código em runtime que um compilador "normal", nunca pode optimizar tanto o código como um compilação executada previamente que pode demorar o tempo que quiser para executar passos de optimização no código. O JVM tem de fazer um tradeoff entre tempo de compilação e nível de optimização.
Eu posso estar a dizer uma grande parvoice mas para mim a performance é algo relativo.
Por exemplo para mim Java e C# tem boa performance em maquinas com bons recursos, consome muito mas da uso a esse consumo. Por outro lado Python e Ruby mesmo em maquinas com bons recursos elas não consomem muito mas também não são muito rápidas.
Ou seja tudo depende de para o que é projectado, normalmente uso Java para sistemas à vontade de recursos e Python para fazer o equivalente mas com menos recursos. C# já tenho ando para começar nesta linguagem mas ainda não vi grande vantagens face ao Java por isso ainda não investi lol
Parece que não estás a par do funcionamento de VMs modernas.
Aqui ficas com um link da Wikipedia que deverá ajudar: http://en.wikipedia.org/wiki/Just-in-time_compilation
A complexidade de código cross-platform continua a existir. Apenas está escondida e é executada num nível diferente dos compiladores tradicionais. A fase de Code generation é deixada para runtime (assim pode gerar código mais adaptado ao processador) em vez de ser gerada anteriormente pré-execução. Existe mesmo uma técnica para VMs, que permite compilar o código na sua totalidade (não tenho a certeza se é mesmo todo) antes da sua execução, chamada AOT (este artigo é fraquinho, mas dá para ter uma ideia).
Triton, desculpa mas esses links não fundamentam a tua opinião na página anterior. Lá porque existem e são usados não quer dizer que sejam a base da JVM da sun, ou de qualquer outra. Aliás, todo e qualquer bytecode em toda e qualquer VM que implemente as especificações da linguagem Java. Independentemente de se usar JIT compilation ou não.
E sejamos francos, há aqui alguem que tem conhecimento sólido da máquina de java? duvido que haja aqui uma única pessoa que seja que tenha por exemplo uma ideia dos seus registos. Pelo que não vejo onde chegaremos se os nossos argumentos se basearem no funcionamento de máquinas virtuais.
Se fizeres um exercício de lógica relativamente simples... Estás a pegar no conceito de compilação JIT e usa-lo para provar que o java é mais lento por causa do overhead que isso adiciona, etc. mas na verdade esse tipo estratégia de execução de bytecode só foi criado para melhorar o desempenho, caso contrario nem sequer existia.
O único fallback deste raciocínio seria se os engenheiros da microsft, sun, google (python) estivessem todos a cometer um erro colossal, o que tem uma probabilidade que tende para zero.
C# já tenho ando para começar nesta linguagem mas ainda não vi grande vantagens face ao Java
É porque não existem, é um produto projectado e implementado para exactamente o mesmo segmento de mercado, tentando brilhar em todos os pontos onde o outro já brilha. É uma questão simplesmente de variedade de oferta no mercado, nada mais.
pedrotuga, não percebi o que estás a tentar dizer.
pedrotuga, embora possamos dizer que a JVM é uma máquina virtual, ela não o é no mesmo sentido que máquinas virtuais com VM Server ou Virtual PC, não simulam uma máquina física.
É certo que bytecode é, até certo ponto, código compilado, mas existe um certo parsing desse código. Bytecode é um código intermédio entre código compilado nativamente e código compilado para a plataforma Java. O que dizemos com compilação da JVM ou compilação nativa é que, durante a primeira execução a JVM irá analisar o bytecode, identificar pontos para optimização e pontos para compilação e depois compilar, ou passar esse bytecode para código nativo da plataforma.
Bytecode é código igual, seja qual for a plataforma em que tenha sido compilado, mas durante a execução a JVM passa esse código que é igual para todas as plataformas, para código nativo da plataforma onde a aplicação está a executar. Naturalmente este processo tem um ligeiro overhead, que é absorvido pela maior velocidade de execução da aplicação.
Este processo é tão mais vantajoso quanto mais tempo a aplicação executar, uma vez que a compilação nativa é perdida assim que a aplicação termina, embora isto possa ser modificado.
A ideia de JIT é que a compilação do bytecode torna a execução mais rápida, esse tempo de análise e de compilação é ganho em execução por todas as modificações que são aplicadas ao código.
O que se diz para Java aplica-se de forma similar a C#, tanto em .net como em Mono, embora existam várias diferenças, mas a teoria é a mesma. O tópico é realmente sobre Mono, mas Java é capaz de ser mais conhecido e de parecer menos estanho que o Mono
Como assim não é no mesmo sentido? São VMs precisamente nesse sentido. As diferenças são apenas o uso arquitecturas próprias criadas para o efeito e o facto de apenas simularem um computador propriamente dito e não um sistema informático cheio de periféricos, unidades de memória externa, não sei quantos protocolos de I/O, etc.
É certo que bytecode é, até certo ponto, código compilado, mas existe um certo parsing desse código. Bytecode é um código intermédio entre código compilado nativamente e código compilado para a plataforma Java.
É precisamente isto que eu estou a tentar rebater há não sei quantos posts. O que o bytecode é, é precisamente código máquina, não é nenhum código intermédio, por isso é que este tópico está uma grande confusao. Bytecode é uma sequencia de dados em binário que o processador da máquina virtual entende.
A máquina virtual, é que, por não ser um dispositivo físico e por estar ciente das características do sistema anfitrião, pode, quando se justificar, pegar em parcelas de bytecode, e usar tecnicas de optimização no runtime que é o que se chama compilação just in time.
Uma máquina física não pode obviamente fazer isto porque está ocupada a correr a aplicação em questão. Mas por exemplo, as placas gráficas, devido à quantidade massiva de processamento já vêm com multiplos processadores precisamente para serem usados por esoterismos com nomes tipo 'acelereção gráfica' etc.
O que os mais curiosos e cépticos poderão dizer é:
"Ah pois, mas no fim de contas o processamento terá que passar de uma forma ou de outra no processador físico, logo compilado/interpretado mais uma vez e por isso com muito mais overhead"
E eu não tenho nada a dizer sobre isso. Não faço ideia de como é que as VMs mandam o seu código para o sistema anfitrião. O CLI do .net deve ser fechado, e o Java só é GPL desde há uns dois ou três anos.
Só a título de curiosidade, andei a sondar a implementação do Java do projecto GNU e descobri que já existem compiladores da linguagem Java para código máquina nativo.
Neste tipo de discussão não gosto muito de afixar links da wikipédia porque às vezes não são muito concisos num noutro aspecto. Mas estas leituras basicamente esclarecem esta discussão de forma simples: