Ho due diverse implementazioni di una funzione (ad esempio la dimensione dell'albero) una che è ricorsiva e una che utilizza uno stack esplicito.È sicuro catturare StackOverflowError in Java?
Il ricorsivo è molto veloce (probabilmente perché non ha bisogno di allocare nulla sullo heap) ma può causare uno stack overflow su alcuni input "rari" (nell'esempio dell'albero, sarebbe su qualsiasi albero non bilanciato) . La versione esplicita è più lenta ma è improbabile che causi un overflow dello stack.
Quanto è sicuro utilizzare l'implementazione ricorsiva per impostazione predefinita e ripristinare dall'eccezione StackOverflowError eseguendo quella esplicita?
È considerato una cattiva pratica?
Ecco un piccolo esempio di codice:
interface Node {
List<? extends Node> getSons();
}
static int sizeRec (Node root) {
int result = 1;
for (Node son : root.getSons()) {
result += sizeRec(son);
}
return result;
}
static int sizeStack (Node root) {
Stack<Node> stack = new Stack<Node>();
stack.add(root);
int size = 0;
while (! stack.isEmpty()) {
Node x = stack.pop();
size ++;
for (Node son : x.getSons()) {
stack.push(son);
}
}
return size;
}
static int size (Node root) {
try {
return sizeRec(root);
} catch (StackOverflowError e) {
return sizeStack(root);
}
}
quanto ne sappia io, non ci sono problemi con la cattura StackOverflowError - è solo una cosa molto raro bisogno di fare, e * la maggior parte del tempo * indica un bug, piuttosto che una struttura di dati troppo complessa per elaborare in modo ricorsivo . – immibis
Come si quantifica più veloce e più lento in questo caso? L'hai punto di riferimento? Se sì, come? –
@immibis: non ne sono così sicuro. Se noti l'eccezione, allora cosa? Probabilmente il tuo stack non è in uno stato sostenibile, quindi come ti riprenderesti da tale errore e sarai certo che il tuo programma sia stabile? –