2010-07-18 6 views
10

Sto scrivendo un codice Clojure che dipende da un numero di costanti.Qual è l'equivalente Clojure di una costante "finale statica pubblica" in Java

Saranno utilizzati all'interno di loop interni stretti, quindi è importante che vengano utilizzati e ottimizzati nel modo più efficiente possibile dalla combinazione Clojure Compiler + JVM. Normalmente usavo una costante "finale statico pubblico" in Java per lo stesso scopo.

Qual è il modo migliore per dichiararli?

risposta

6

Penso che def -le cose nello spazio dei nomi globale sia il più vicino possibile.

+2

Aggiungendo il:: i metadati const causeranno il loro allineamento al momento della compilazione, vedere risposta di @amalloy. I difetti globali sono vars, che mentre sono chiusi, possono essere modificati e risolti in fase di esecuzione. – deterb

2

come detto sopra usare def o atomo, ricordate, i dati sono immutabili, quindi se dichiarate delle costanti in una lista, non cambiano.

+0

Se desiderava qualcosa di mutabile, chiedeva una costante e comunque tu normalmente rendi una lista con gli atomi. Faresti una lista di atomi o una lista di referenze. – nickik

2

Non c'è il numero defconst, quindi è sufficiente usare una def globale per definire l'idioma; per quanto riguarda l'ottimizzazione, il JIT renderà le cose veloci.

3

Se davvero, davvero, davvero vuole la costante sul posto (credo, la JIT noterà che il valore è costante e fa la cosa giusta, però), è possibile utilizzare una macro.

(defmacro my-constant [] 5)

Questo è piuttosto brutto, ma il codice critico delle prestazioni sarà sempre brutto, immagino.

(do-stuff (my-constant) in-place)

Prestare attenzione a ciò che si inserisce nella macro, però! Non lo farei per più di alcune costanti letterali. In particolare non oggetti.

3

Se solo utilizzando def non è abbastanza veloce, è possibile provare a creare un alias associato let prima di immettere il ciclo stretto per evitare di passare attraverso un var ogni volta.

+0

Grazie - così ho ragione nel dire che se non lo fai, allora finirà per dereferenziare la var ogni volta che si accede alla costante? – mikera

6

Credo che Clojure 1.3 (o forse 1.4) consente di inserire un tag ^:constant su un def, indicando al compilatore che questa dovrebbe essere una costante e tutti i riferimenti dovrebbero essere risolti in fase di compilazione.

Modifica

a quanto pare è Clojure 1.3, ed è ^:const, non ^:constant. Vedi How does Clojure ^:const work? per un sommario.

Problemi correlati