C'è qualche motivo di prestazioni per dichiarare i parametri del metodo definitivi in ​​Java?


117

C'è qualche motivo di prestazioni per dichiarare i parametri del metodo definitivi in ​​Java?

Come in:

public void foo(int bar) { ... }

Contro:

public void foo(final int bar) { ... }

Supponendo che barvenga solo letto e mai modificato in foo().


Non riesco a pensare a un motivo per cui il compilatore si preoccuperebbe se dichiarassi un parametro del metodo finale o meno. Ma la vera risposta a questa domanda è: scrivi due funzioni, una con i parametri finali e una con i parametri regolari. Eseguili un milione di volte ciascuno e vedi se c'è qualche differenza di runtime notevole. Se sei preoccupato per le prestazioni, è molto importante fare del lavoro di profilazione sul tuo codice e scoprire esattamente cosa ti sta rallentando. Quasi certamente non è quello che ti aspetteresti che sia :)
Mike Blandford

1
Suggerirei di non scrivere mai micro benchmark. Non sai quale ottimizzazione può fare il JIT e quando, e probabilmente ti faresti un'idea sbagliata di come si comporta solo facendo un "semplice test case"
Edmondo1984

beh, potrebbe essere, ma nessuno qui ha scritto o suggerito un microbenchmark ...
Kip

1
La risposta di @Mike Blandford suggerisce di utilizzare un micro-benchmark, no?
Ben Page

Scrivere micro benchmark in Java è qualcosa di molto molto complicato
Edmondo1984

Risposte:


97

La parola chiave finale non appare nel file di classe per variabili e parametri locali, quindi non può influire sulle prestazioni di runtime. È solo utile per chiarire l'intento dei programmatori di non modificare la variabile (che molti considerano una ragione dubbia per il suo utilizzo) e gestire classi interne anonime.

Ci sono molte discussioni sul fatto che il modificatore finale del metodo stesso abbia un miglioramento delle prestazioni poiché i metodi saranno comunque integrati dal compilatore ottimizzante in fase di esecuzione, indipendentemente dal modificatore. In questo caso dovrebbe essere utilizzato anche solo per limitare l'override del metodo.


5
penseresti che le variabili / parametri finali potrebbero essere ottimizzati come variabili di ciclo però ... ma un buon compilatore / runtime dovrebbe essere in grado di capirlo senza finale comunque ...
John Gardner,

9
Ho visto il compilatore di Sun emettere bytecode leggermente più corto quando l'unica differenza tra i due metodi era la "finalità" delle variabili locali. Le micro-ottimizzazioni sono una cosa reale e i compilatori le realizzano effettivamente. Ciò che conta davvero, ovviamente, è ciò che il JIT fa con il bytecode, ei riferimenti locali perdono la loro "finalità" quando vengono compilati in bytecode. Penso che questo sia il motivo per cui ci sono così tante speculazioni sulle variabili locali finali: è abbastanza non deterministico quali siano i risultati. Tuttavia, l'utilizzo di locals finali può influire sul bytecode, per quello che vale.
Christopher Schultz

Poiché non è deterministico, non c'è davvero alcun modo per dipendere dall'ottimizzazione. Ovviamente, molto potrebbe essere cambiato nelle implementazioni della VM dalla risposta originale nel 2008 ;-)
Robin

15

L'unico vantaggio di un parametro finale è che può essere utilizzato in classi annidate anonime. Se un parametro non viene mai modificato, il compilatore lo rileverà già come parte del suo normale funzionamento anche senza il modificatore finale. È piuttosto raro che i bug siano causati da un parametro assegnato inaspettatamente - se i tuoi metodi sono abbastanza grandi da richiedere questo livello di ingegneria, rendili più piccoli - i metodi che chiami non possono cambiare i tuoi parametri.


8
"È piuttosto raro che i bug siano causati da un parametro assegnato in modo imprevisto". È più comune di quanto pensi ...
RAY

2
@RAY potresti avere ragione, in realtà non ho dati (oltre alla mia esperienza) per sostenere tale affermazione.
Dobes Vandermeer

@DobesVandermeer per essere più precisi, questo non è davvero un "vantaggio per un parametro finale ". Ciò che stai descrivendo è semplicemente la sintassi richiesta per qualsiasi variabile locale (di cui includo i parametri come) da rendere visibile all'ambito locale della classe annidata anonima.
swooby

0

I compilatori che operano dopo il caricamento della classe, come i compilatori JIT, possono trarre vantaggio dai metodi finali. Di conseguenza, i metodi dichiarati definitivi potrebbero avere qualche vantaggio in termini di prestazioni.

http://www.javaperformancetuning.com/tips/final.shtml

Oh e un'altra buona risorsa

http://mindprod.com/jgloss/final.html


10
La domanda riguardava i parametri dichiarati definitivi, il che non ha alcun impatto sulle prestazioni.
Robin

Sul moderno JIT'S (Hotspot) la finale non ha alcuna influenza (misurabile) sulle prestazioni, sia applicata ai parametri che alla classe
kohlerm

2
I due articoli a cui colleghi entrambi suggeriscono che final è piuttosto un segno semantico per gli sviluppatori e che i compilatori JIT possono utilizzare final (ma come altri hanno sottolineato, non hanno davvero bisogno di queste informazioni). Quindi il finale è piuttosto semantico, il che è in parallelo con la capacità dei moderni compilatori C / ++ di dedurre la costanza di variabili e metodi anche se non sono contrassegnati esplicitamente da const.
ron

0

Solo un altro punto che sopra l'uso di variabili locali non finali dichiarate all'interno del metodo: l'istanza della classe interna potrebbe sopravvivere allo stack frame, quindi la variabile locale potrebbe svanire mentre l'oggetto interno è ancora vivo


-2

Presumo che il compilatore possa eventualmente rimuovere tutte le variabili finali statiche private che hanno un tipo primitivo, come int, e inserirle direttamente nel codice proprio come con una macro C ++.

Tuttavia, non ho idea se ciò sia fatto in pratica, ma potrebbe essere fatto per risparmiare un po 'di memoria.


La domanda non riguarda le variabili finali private statc.
Marchese di Lorne
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.