2012-11-20 12 views
5

catch in Ruby è pensato per saltare fuori dal codice profondamente annidato. In Java, ad es. è possibile ottenere lo stesso con Java try-catch destinato alla gestione delle eccezioni, tuttavia è considerato una soluzione scadente ed è anche molto inefficiente. In Ruby per la gestione delle eccezioni abbiamo begin-raise-rescue e presumo che sia anche costoso utilizzarlo per altre attività.ruby ​​catch-throw ed efficienza

Ruby catch-throw è davvero una soluzione più efficiente di begin-raise-rescue o ci sono altri motivi per utilizzarlo per rompere blocchi nidificati anziché begin-raise-rescue?

+0

Se pubblichi alcuni esempi di rubini delle strutture di controllo che stai chiedendo, potrebbe essere più chiaro cosa intendi. –

risposta

5

Oltre ad essere il modo "corretto" per uscire dalle strutture di controllo, catch-throw è anche significativamente più veloce (10 volte più veloce nei miei test). Controlla this gist per il mio codice e risultati.

+0

+1 per il benchmarking. – steenslag

+0

Grazie! Il punto di riferimento cancella davvero il problema (nel mio caso è quasi 15 volte!). Il catch-throw dovrebbe essere considerato uno stile strutturale di programmazione - una pratica migliore è quindi disprezzata? – wrzasa

+0

Il tuo progetto richiede un tiro di apertura, probabilmente c'è un design migliore. Detto questo, ci sono sicuramente casi limite in cui il catch catch ha molto senso, specialmente nello sviluppo di gemme in cui non si sa come l'utente userà. – Josh

5

Josh's answer è corretto. Voglio aggiungere ulteriori informazioni su catch-throw e raise-rescue.

catch-throw viene utilizzato per il controllo di flusso mentre raise-rescue viene utilizzato per la gestione di eccezioni/errori. Il diverso è: backtrace non è necessario per catch-throw (controllo di flusso). Fidati di me, il motivo principale per cui le cause raise-rescue si eseguono lentamente rispetto a catch-throw 10 volte in Josh's gist è raise-rescue richiede molto tempo per creare l'oggetto backtrace.

Se si vuole raise senza backtrace, utilizzare la sintassi:

raise <type>, <message>, <backtrace> 

Checkout my gist. raise without backtrace è molto più veloce di raise with backtrace.

aprile 2016 Aggiornamento:

Ho aggiornato my gist:

  • fisso "rompere" test
  • Aggiunto test di benchmark risultati per più recente rubino versione 2.1.8, 2.2.4, 2.3.0