PS: se trata de emulação de uma cpu, portanto não estou seguindo muito os padrões e melhores práticas em função da performance.
Com o tópico http://guj.com.br/posts/list/64849.java já respondido.
Veio outra indagação
veja:
Com switch.
switch (opcode)
{
case 0x0001:
method1();
case 0x0002:
method2();
case 0x0003:
method3();
...
case 0x00FF
}
(essa coisa compilada provavelmente dará em um monte de if’s aninhados)
Com Reflection:
[quote]Method metodo = this.getClass().getMethod( “method” + opcode );
metodo.invoke();[/quote]
Mas ai veio a dúvida a cada chamada no Reflaction irá causar um I/O no disco ?
Se sim, então é bem menos rápido.
Estou certo?
Ele nao causara uma I/O no disco… pois ele não dispara uma IOException… ele usa a propria memoria para fazer isto provavelmente…
mas pelo que eu vejo e bem mais performatico usar blocos switch invez de reflection… e melhor ainda usar Interfaces para isto…
Usualmente você usaria “switch” mesmo para efetuar sua emulação. Ou então faria o seguinte:
interface Processavel {
void processar();
}
class NOP implements Processavel {
public void processar () {}
}
class ADD implements Processavel {
private Contexto cont;
public ADD (Contexto cont) {
this.cont = cont;
}
void processar () { cont.registradorA = cont.registradorA + cont.registradorB; }
}
class SUB implements Processavel {
private Contexto cont;
public SUB (Contexto cont) {
this.cont = cont;
}
void processar () { cont.registradorA = cont.registradorA - cont.registradorB; }
public class CPU {
Contexto contexto = new Contexto();
Processavel opcodes = new Processavel [] {
new NOP(), // opcode 0x0000
new ADD(cont), // opcode 0x0001
new SUB(cont),
....
};
int instrucoes[] = ...;
public void emular () {
...
// Executando a instrução do array instrucoes
// cuja posição está em "contexto.pc"
opcodes[instrucoes[contexto.pc]].processar();
...
}
}
}
Apenas três coisas:
a) Reflection incorre uma perda na ordem de 5%. O ideal é você poder usar algo como a nova API de Compiler do Java 6 ou o Janino para Compilar isto em uma classe que implemente uma interface, e/ou uma classe abstrata. Segue um exemplo de um código que implementei semana passada, utilizando o janino:
/**
* Compila/Instancia um Verifier a partir do código-fonte especificado
*
* @param text
* codigo-fonte do verifier
* @return verifier
*/
private Verifier getVerifier(final String text) {
try {
final ClassBodyEvaluator classBodyEvaluator = new ClassBodyEvaluator();
classBodyEvaluator.setDefaultImports(new String[] {
SerializedDataVerifier.class.getCanonicalName(),
Verifier.class.getCanonicalName(),
AbstractVerifier.class.getCanonicalName() });
classBodyEvaluator.setImplementedTypes(new Class[] { Verifier.class });
classBodyEvaluator.setExtendedType(AbstractVerifier.class);
classBodyEvaluator
.cook(String
.format(
"protected void verifyInternal(VerifierSource verifierSource) { %s }",
this.text));
return (Verifier) classBodyEvaluator.getClazz().newInstance();
} catch (final Exception e) {
throw new IllegalArgumentException(String.format("getVerifier(text=%s)", text), e);
}
}
Este código me cria uma classe derivada de AbstractVerifier (que roteia para verifyInternal) e que implementa a interface Verifier, a partir do conteúdo de texto. Resumindo, é um Pattern de Command, de forma que possa ser usado em uma cadeia-de-responsabilidade maior.
No caso, a única coisa que faço é uma interpolação entre um template de código-fonte, de forma a construir os métodos. É uma boa idéia? Sem dúvida: Reavaliar periodicamente o mesmo bloco de código não é uma boa idéia, quando o que você quer é performance.
Mas lembre-se: Otimização prematura é a fonte de toda a maldade no mundo 
b) Existe um opcode específico, otimizado para switches. Este artigo pode te dar mais detalhes
c) Existe limite de 64KiB para comprimento do método.
Espero que ajude.
p/S: Pelo pouco que li do seu projeto, acho que você pode aprender algumas coisas lendo os artigos do NestedVM, que é um emulador de MIPS feito para executar sob uma JVM.
Muito obrigado !!!
Vou usar as informações citadas por vocês.