Existe um conceito de funções inline em java ou substituiu alguma outra coisa? Se houver, como é usado? Já ouvi isso public
, static
e os final
métodos são funções embutidas. Podemos criar nossa própria função embutida?
Existe um conceito de funções inline em java ou substituiu alguma outra coisa? Se houver, como é usado? Já ouvi isso public
, static
e os final
métodos são funções embutidas. Podemos criar nossa própria função embutida?
Respostas:
Em Java, as otimizações geralmente são feitas no nível da JVM. No tempo de execução, a JVM executa algumas análises "complicadas" para determinar quais métodos embutir. Ele pode ser agressivo no in-line, e o Hotspot JVM pode, na verdade, métodos inline não finais.
Os compiladores java quase nunca embutem nenhuma chamada de método (a JVM faz tudo isso em tempo de execução). Eles fazem constantes de tempo de compilação em linha (por exemplo, valores primitivos estáticos finais). Mas não métodos.
Para mais recursos:
Artigo: O Java HotSpot Performance Engine: Método Inlining Exemplo
Wiki: Inlining no OpenJDK , não totalmente preenchido, mas contém links para discussões úteis.
Não, não há função embutida em java. Sim, você pode usar um método estático público em qualquer lugar do código quando colocado em uma classe pública. O compilador java pode fazer expansão sequencial em um método estático ou final, mas isso não é garantido.
Normalmente, essas otimizações de código são feitas pelo compilador em combinação com o JVM / JIT / HotSpot para segmentos de código usados com frequência. Além disso, outros conceitos de otimização, como declaração de registro de parâmetros, não são conhecidos em java.
Otimizações não podem ser forçadas por declaração em java, mas feitas por compilador e JIT. Em muitas outras linguagens, essas declarações são freqüentemente apenas dicas do compilador (você pode declarar mais parâmetros de registro do que o processador, o resto é ignorado).
Declarar métodos java como static, final ou private também são dicas para o compilador. Você deve usá-lo, mas sem garantias. O desempenho do Java é dinâmico, não estático. A primeira chamada para um sistema é sempre lenta devido ao carregamento da classe. As próximas chamadas são mais rápidas, mas dependendo da memória e do tempo de execução, as chamadas mais comuns são otimizadas dentro do sistema em execução, de modo que um servidor pode se tornar mais rápido durante o tempo de execução!
final
não causa impacto no JIT inlining
Java não fornece uma maneira de sugerir manualmente que um método deve ser embutido. Como @notnoop diz nos comentários, o inlining é normalmente feito pela JVM em tempo de execução.
jdk.internal.vm.annotation.ForceInline
O que você disse acima está correto. Às vezes, os métodos finais são criados como sequenciais, mas não há outra maneira de criar explicitamente uma função sequencial em java.
final
não faz nenhuma diferença se o método é embutido ou não.
Exemplo da vida real:
public class Control {
public static final long EXPIRED_ON = 1386082988202l;
public static final boolean isExpired() {
return (System.currentTimeMillis() > EXPIRED_ON);
}
}
Então, em outras aulas, posso sair se o código tiver expirado. Se eu fizer referência à variável EXPIRED_ON de outra classe, a constante é embutida no código de byte, tornando muito difícil rastrear todos os lugares no código que verifica a data de validade. No entanto, se as outras classes invocarem o método isExpired (), o método real é chamado, o que significa que um hacker pode substituir o método isExpired por outro que sempre retorna falso.
Concordo que seria muito bom forçar um compilador a embutir o método final estático em todas as classes que fazem referência a ele. Nesse caso, você não precisa nem incluir a classe Control, pois ela não seria necessária em tempo de execução.
Pela minha pesquisa, isso não pode ser feito. Talvez algumas ferramentas do Obfuscator possam fazer isso, ou você pode modificar seu processo de construção para editar as fontes antes de compilar.
Para provar se o método da classe de controle é colocado embutido em outra classe durante a compilação, tente executar a outra classe sem a classe Control no caminho de classe.
Bem, existem métodos que podem ser chamados de métodos "inline" em java, mas dependendo do jvm. Após a compilação, se o código de máquina do método for menor que 35 bytes, ele será transferido para um método embutido imediatamente; se o código de máquina do método for menor que 325 bytes, ele pode ser transferido para um método embutido, dependendo do jvm.
então, parece que não existe, mas você pode usar esta solução alternativa usando goiaba ou uma implementação de classe de função equivalente, porque essa classe é extremamente simples, por exemplo:
assert false : new com.google.common.base.Function<Void,String>(){
@Override public String apply(Void input) {
//your complex code go here
return "weird message";
}}.apply(null);
sim, este é um código morto apenas para exemplificar como criar um bloco de código complexo (dentro de {}) para fazer algo tão específico que não deve nos incomodar em criar qualquer método para isso, também conhecido como inline!