2012-06-11 1 views
8

So che entrare in un blocco catch ha un costo significativo quando si esegue un programma, tuttavia, mi chiedevo se l'inserimento di un blocco try {} avrebbe avuto un impatto, quindi ho iniziato a cercare una risposta in google con molte opinioni, ma nessun benchmarking. Alcune risposte che ho trovato sono stati:Benchmark di Java Try/Catch Block

  1. Java try/catch performance, is it recommended to keep what is inside the try clause to a minimum?
  2. Try Catch Performance Java
  3. Java try catch blocks

Tuttavia, essi non hanno risposto alla mia domanda con i fatti, così ho deciso di provare per me.

Ecco cosa ho fatto. Ho un file CSV con questo formato:

host;ip;number;date;status;email;uid;name;lastname;promo_code;

dove tutto dopo lo stato è facoltativo e non avrà nemmeno la corrispondente; quindi, quando si analizza una convalida per verificare se il valore è presente, ecco dove mi è venuto in mente il problema try/catch.

Il codice attuale, che ho ereditato nella mia azienda fa questo:

StringTokenizer st=new StringTokenizer(line,";"); 
String host = st.nextToken(); 
String ip = st.nextToken(); 
String number = st.nextToken(); 
String date = st.nextToken(); 
String status = st.nextToken();        
String email = ""; 
try{ 
    email = st.nextToken(); 
}catch(NoSuchElementException e){ 
    email = ""; 
} 

e ripete ciò che è fatto per la posta elettronica con uid, nome, cognome e promo_code.

e ho cambiato tutto per:

if(st.hasMoreTokens()){ 
    email = st.nextToken(); 
} 

e in effetti esegue più veloce. Durante l'analisi di un file che non ha le colonne opzionali. Qui ci sono i tempi medi:

--- Trying:122 milliseconds 
--- Checking:33 milliseconds 

però, ecco quello che io e la ragione per cui sto chiedendo confuso: Quando si esegue l'esempio con i valori per le colonne opzionali in tutte le 8000 linee del CSV, la versione se() esibisce ancora migliore rispetto alla versione try/catch, quindi la mia domanda è

fa davvero il blocco try non hai alcun impatto sulle prestazioni sul mio codice?

I tempi medi per questo esempio sono:

--- Trying:105 milliseconds 
--- Checking:43 milliseconds 

Qualcuno può spiegare cosa sta succedendo qui?

Grazie mille

+0

ogni volta che si verifica la condizione si rallenta il programma. Non è una buona idea avere più istruzioni IF. Il tuo approccio aziendale sembra comprensibile. Ogni volta che vengono sollevati errori, puoi avere un blocco catch per vedere di cosa si tratta. –

+0

Non vorrei secondarlo. Nel suo caso, l'email è facoltativa, quindi 'st' non avere più token non è un caso eccezionale, ma può accadere molto spesso. Usare un'eccezione qui non è un buon stile. – gexicide

+0

Non solo accadrà molto spesso, è il comportamento predefinito. Avremo solo i campi opzionali in molte piccole occasioni – hectorg87

risposta

10

Sì, provare (in Java) non ha alcun impatto sulle prestazioni. Il compilatore non genera istruzioni VM per un blocco try. Registra semplicemente i contatori del programma tra i quali il blocco try è attivo e allega queste informazioni al metodo nel file di classe. Quindi, quando viene lanciata un'eccezione, la VM disattiva lo stack e controlla su ciascun frame se il contatore del programma in quel frame si trova in un blocco try rilevante. Questo (insieme alla costruzione della traccia dello stack) è piuttosto costoso, quindi la cattura è costosa. Tuttavia, provare è gratis :).

Tuttavia, non è consigliabile utilizzare le eccezioni per il flusso di controllo regolare.

Il motivo per cui il codice esegue più rapidamente è probabilmente che la cattura è così estremamente costosa da superare il tempo risparmiato sostituendo il controllo con un semplice tentativo.

Provare a catturare può essere più veloce nel codice in cui il fermo viene attivato non molto spesso, ad esempio, se si tenta di provare 10000 volte ma si cattura solo una volta, il metodo di prova sarebbe più veloce del controllo if. Tuttavia, questo non è un buon stile e il tuo modo di verificare esplicitamente più token è da preferire.

+0

Grazie, lo capisco davvero, tuttavia il il codice che ho provato dice diversamente, funziona come il try {} è un sovraccarico in fase di esecuzione, ed è di questo che si tratta la mia domanda.Posso incollare il codice del test da qualche parte così puoi provarlo e vedere di persona. – hectorg87

+0

ok, capisco. Bene, il problema potrebbe essere che la prova è più difficile da ottimizzare. Tuttavia, l'impatto sulle prestazioni è trascurabile comunque. Come regola generale, non si dovrebbe mai considerare di scambiare se con try/catch per ragioni di ottimizzazione. Basta usare try/catch per un comportamento eccezionale e se per un controllo regolare del flusso. Tutto il resto è un hack. – gexicide

+0

I tempi indicati nella mia domanda sono 1) quando inserisco il blocco catch SEMPRE (8000 volte * 5 colonne) e 2) non inserendo il blocco catch mai perché le colonne opzionali ci sono sempre – hectorg87