| Autor |
Mensagem |
|
|
cv wrote:
Não é por causa dos tipos primitivos que o Java hoje tem uma performance boa. É por causa do HotSpot, e este continua indo muito bem, obrigado, e não tem nenhuma dependência vital em cima de tipos primitivos pra funcionar direito. Depois, é possível ter tipos primitivos no bytecode, sem tê-los na linguagem.
HotSpot não faz nenhuma magica, é simplesmente um JIT'er que faz compilação seletiva. Não sei sobre seu conhecimento técnico no assunto, mas pelo que você disse, pouco sabe.
Se java não tivesse tipos primitivos sua performance numérica seria mais de 1 ordem de magnitude inferior ao equivalente em C, oque não é verdade. E pq isso? Mágica? Ou pelo fato que operações com tipos primitivos são traduzidas em menos instruções de máquina, instruções mais rapidas tb. Considere os seguintes pseudo-código:
(1)
int a = 10;
int b = 20;
c = a + b; //c é uma variavel estatica
(2)
Integer a = 10; //autoboxed
Integer b = 20; //autoboxed tambem
c = a + b; //mesmo c do outro snippet.
Se você possui algum conhecimento sobre assembly e o formato de bytecode usado por java/.net/etc vai entender o seguinte, que seria o resultado traduzido pelo compilador. (em pseudo instrucoes de java bc, pq nao tenho referencia a mao)
(1)
push 10
push 20
add_i
store_static [c]
(2)
push 10
new Integer(int)
push 20
new Integer(int)
call_vfunc [add]
store_static [c]
(1) em assembly pode ser traduzido (pra asm intel):
mov eax, 10
add eax, 20
mov [c], eax
(2) em contrapartida
//contruimos o primeiro Integer
mov eax, 10
call [new_integer_int]
//construimos o segundo Integer
mov ebx, eax
mov eax, 20
call [new_integer_int]
//chamamos o metodo virtual add da classe Integer
push eax
push ebx
lea eax, [eax + 20 ] //suponhamos que 20 seja o offset do metodo add
call eax
sub esp, 8
mov [c], eax
Isso é algo bem por cima, tou supondo que temos 1 standard call sequence (eax volatil, parametros pela pilha pushed da esquerda pra direita, caller da pop), como era na vm da 1.3 se lembro bem...
Ou seja, trocamos uma sequencia de 3 instrucoes por uma de 11 sem contar oque ocorre dentro das 3 chamadas de funcao, que vai envolver alocacao de memoria 2x pelo menos.
Nem utilizando técnicas como desvirtualização e stack object allocation a performance chega perto do equivalente tendo tipos primitivos.
O cara da reportagem não quer programar em java, mas sim em python, la isso ocorre, la vc vai aceitar 1 programa que roda mais de 100x mais lento que o equivalente em C.
louds wrote:
longs e doubles devem continuar nao sendo atomicos, ou entao vamos tornar operacoes com eles absurdamente lentas os plataformas 32 bits. Por curiosidade, quantos aqui usam predominantemente ambientes 64 bits?
cv wrote:
De novo, HotSpot neles!
Não vou colocar 1 monte de código assembly dessa vez pq não precisa, que diabos a VM pode fazer pra milagrosamente tornar operações em long e double atômicas num pc ou mac? A única maneira é tendo sincronização automática, oq vai tornar criptografia, por exemplo, razoavelmente mais lenta, imagina que o compilador, pela suas costa iria fazer o seguinte:
long x = 10;
long y = 20;
synchronized(BIG_VM_LOCK) {
y = x;
}
louds wrote:
Sobre a parte de arruma o mecanismo de classloading, eh sim confuso, porem a interface do ClassLoader funciona ok e o problema que o autor se refere eh falha do software dele, onde os 2 classloaders carregar a mesma interface...
cv wrote:
O problema não é se funciona, é se funciona da melhor maneira possível e se é fácil de usar. Todos nós sabemos que os ClassLoaders hoje funcionam, mas eles são mesmo a melhor solução?
Que escrever 1 classloader legal é a coisa mais dificil que a 1.4 oferece, sem dúvidas, mas é dificil pensar em uma alternativa que também nao seja horrivel de usar...
cv wrote:
Pode ser... algo como:
[]'s
-cv
Sera nao rolava ser algo automatico baseado nos header da classe?
algo do tipo
__attribute(java3) class Main { ... }
Ok, tou roubando sintaxe do gcc, mas oq vale é a ideia.
Oque seria muito legal num java3 seria completar a parte de reflection, criar 1 forma de poder obter as mesmas informacoes que da via a API mas interagindo diretamente com a classe (Integer.class x this.getClass())
seria muuuito util se desse pra fazer isso com todo o resto, metodos, variaveis, etc. Isso iria causar 1 boom na utilização de reflection.
Outra coisa seria permitir anexar metadata a classes, metodos e variaveis, ./- como rola no c#.
Isso ia permitir que muita da semantica que precisamos passar via arquivos xml pros programas ficasse na classe.
Um exemplo seria colocar toda informação de persistencia como metadata pro OJB usar...
|
 |
|
|
Algumas ideia sao boas, outras sao completamente infundadas.
Tirar os tipos primitivos eh abrir mao de qualquer possibilidade de java ter uma performance aceitavel, vide smalltalk, eh bunitinho e tudo mais, mas pra uso no mundo real eh descartavel.
longs e doubles devem continuar nao sendo atomicos, ou entao vamos tornar operacoes com eles absurdamente lentas os plataformas 32 bits. Por curiosidade, quantos aqui usam predominantemente ambientes 64 bits?
Desacomplar os monitores dos objetos nao eh ruim, vai simplificar bastante o codigo de locking da JVM, porem vai exigir a criacao explicita de objetos pra realizar contencao. O argumento que um objeto nao pode ter mais de 1 monitor eh enrolacao, hoje em dia tem de criar varios Objects somente pra fazer essa tarefa, desacomplando os monitores teria de criar monitores para todas situacoes. O bom eh que nao iria mais ocorrer erros comuns como escolher o objeto errado pra sincronizar quando for realizar uma operacao atomica.
Ja converter os arquivos de properties pra xml acho inutil tb, isso vai na mesma linha dos problemas com ejb, de usar por puro modismo, se faz algum sentido usar ok, perfeito, mas se isso so vai piorar as coisas, ai nao. No caso do arquivo de properties, ate seria interessante se tiver a opcao de adiconar beans serializados como valor de uma property.
Sobre a parte de arruma o mecanismo de classloading, eh sim confuso, porem a interface do ClassLoader funciona ok e o problema que o autor se refere eh falha do software dele, onde os 2 classloaders carregar a mesma interface...
De resto, as propostar dele pra uma limpesa na linguagem e nas ais sao otimas, primeiro deveriamos resolver o problema doque fazer com as aplicacoes legado.
Pq nao usar um esquema de switching? De tal forma que a VM pudesse operar em modo classico e novo dependendo das classes carregadas
|
 |
|
|
Generics como vai ser na 1.5 foi a pior das besteiras que ja fizeram em nome de ter 'backward compatibily'.
Ela juntou as desvantagens de ambos modelos, com/sem generics, e ainda piorou, pra melhorar ainda mais so falta autounboxing pra fechar a festa.
Sem querer puxar a sardinha pro lado da MS, mas a implementacao de generics em c# vai ser infinitamente melhor.
Primeiro, ja nao basta ter feito errado na primeira vez, repetiram denovo a mesma besteira, tipos covariantes que nao deveriam ser, como arrays. Pra quem nao sabe, me refiro ao fato de 1 array de referencias poder ser downcasted para array de uma superclasse do tipo da referencia, ex: Integer[] x; Number[] y = x;
Depois o fato da tipagem dos generics ser fraca, pq qualquer coisa faz vc perder essa informacao, devido a covariancia dos tipos genericos, veja 1 exemplo VALIDO do uso de generics:
List<Integer> x = new ArrayList<Integer>();
List y = x; //toda informacao de tipagem acabou de ir pro espaco
List<Class> z = (List<Class> y; //pior de tudo isso nao gera execessao
z.add(String.class); //e isso tb funciona
Ou seja, que acreditou que Generics vai atenuar erros envolvendo CastCastExceptions no uso de Collections se enganou, serao menos, mas alguns poucos vao ser realmente complexos de serem encontrados, dive o exemplo acima.
Outra era a espectativa de um ganho consideravel em performance por poder especializar em tipo primitivos, oque nao vai poder e agora com autoboxing, maioria vai deixar de reclamar pq agora List.add(1) funciona.
A unica coisa boa dos generics eh a opcao de poder definir contrains pros tipos a serem usados.
|
 |
|
|
|
|