Domanda

Le persone affermano che l'implementazione del clojure è eccellente a parte la limitazione di non avere l'ottimizzazione delle chiamate di coda - una limitazione del jvm non dell'implementazione del clojure.

http://lambda-the-ultimate.org/node/2547

È stato detto che l'implementazione del TCO in Python sacrificherebbe

  • dump dello stack-trace e
  • regolarità di debug.

Spiegami qual è il grosso problema con l'ottimizzazione delle chiamate di coda e perché Python ne ha bisogno

Dovrebbero essere fatti gli stessi sacrifici per un'implementazione jvm di TCO? Qualcos'altro dovrebbe essere sacrificato?

È stato utile?

Soluzione

Anche se diversi (in quanto esistevano già le istruzioni), vale la pena notare lo sforzo aggiuntivo di .Net team JIT a 64 bit ha dovuto passare per rispettare tutte le chiamate di coda.

Chiamo in particolare il commento:

  

Il rovescio della medaglia ovviamente è che se devi eseguire il debug o profilare il codice ottimizzato, preparati a gestire stack di chiamate che sembrano mancare di alcuni frame.

Penso che sia altamente improbabile che anche JVM possa evitarlo.

Dato che, nelle circostanze in cui è stata richiesta l'ottimizzazione della coda, la JIT dovrebbe presumere che sia richiesto per evitare un overflow dello stack, questo non è qualcosa che può essere semplicemente disattivato nelle build di debug. Non sono molto utili per il debug se si arrestano in modo anomalo prima di arrivare alla parte interessante. L '"ottimizzazione" è in effetti una caratteristica permanente e un problema per le tracce dello stack interessate.

Vale la pena sottolineare che qualsiasi ottimizzazione che eviti di creare un vero stack frame quando fa un'operazione che il programmatore descrive / comprende concettualmente come un'operazione di stack (chiamando una funzione per esempio) causerà intrinsecamente una disconnessione tra ciò che viene presentato all'utente quando esegue il debug / fornisce la traccia dello stack e la realtà.
Ciò è inevitabile in quanto il codice che descrive l'operazione diventa ulteriormente e ulteriormente separato dalla meccanica della macchina a stati che esegue l'operazione.

Altri suggerimenti

Il lavoro è in corso ora per aggiungere chiamate di coda alla JVM. C'è una pagina wiki che parla di alcuni dettagli.

Sì, in genere accade che l'implementazione del TCO ti impedirà di ottenere tracce dello stack completo. Ciò è inevitabile perché il punto centrale di TCO è evitare di creare frame di stack aggiuntivi.

Vale anche la pena notare che Clojure ha un "ricorrente" che non consuma stack funzione per aggirare questo vincolo sulle attuali versioni di JVM.

Esempio:

(defn triangle [n accumulator] 
  (if 
    (<= n 0)  
      accumulator
      (recur (dec n) (+ n accumulator))))

(triangle 1000000 0)

=> 500000500000     (note stack does not explode here!)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top