2014-12-24 19 views
6

Sto usando Scala Enumeration ValueSets in un'impostazione abbastanza elevata, creando, testando, unione e intersecando circa 10 M set/secondo/core. Non mi aspettavo che questo fosse un grosso problema, perché avevo letto da qualche parte che erano supportati da BitSet, ma sorprendentemente ValueSet.isEmpty si presentava come un punto caldo in una sessione di profilazione con YourKit.Enumerazione Scala ValueSet.isEmpty slow

Per verificare, ho deciso di provare e reimplementare ciò di cui avevo bisogno utilizzando il BitSet Java, mentre cercavo di mantenere un po 'della sicurezza del tipo dell'uso di Enumerazioni Scala. (la revisione del codice è stata spostata su https://codereview.stackexchange.com/questions/74795/scala-bitset-implemented-with-java-bitset-for-use-in-scala-enumerations-to-repl) La buona notizia è che, cambiando solo i miei ValueSet su questi BitSet, ho effettivamente perso il 25% del mio tempo di esecuzione, quindi non so cosa stia davvero facendo ValueSet ma potrebbe essere migliorato ...

MODIFICA: L'analisi della sorgente ValueSet sembra indicare che isEmpty è sicuramente O (N), implementato utilizzando il SetLike.isEmpty generale. Considerando che ValueSet è implementato con un BitSet, si tratta di un bug?

MODIFICA: questo era il backtrace del profiler. Questo sembra un modo pazzo per implementare isEmpty su un set di bit.

Backtrace of hot spot in YourKit

+0

"Non so cosa stia davvero facendo ValueSet sotto il cofano". La fonte è disponibile, se volessi dare un'occhiata: https://github.com/scala/scala/blob/v2.11.4/src/library/scala/Enumeration.scala#L1 –

+0

Sembra che tu abbia un codice funzionante su cui vuoi un feedback. In questo caso, dovresti spostare la domanda su [codereview.se]. Altrimenti, per favore abbassa la tua domanda e rendi la domanda reale più evidente - mi ci è voluto un po 'per trovare anche quello che stavi chiedendo. –

+0

Grazie, guardando ora. Finora sembra confermare ciò che ho trovato nel profiler (allegato); il ValueSet.isEmpty, almeno, è implementato interamente con algoritmi generici, trascurando che per un BitSet, non dovrebbe essere più difficile di (x == 0). – experquisite

risposta

1

Per la cronaca, io sono tutto per guardare sotto il cofano, ma questo disegno chiede troppo di qualsiasi coder mortale.

Gli immortali, naturalmente, hanno un tempo infinito a loro disposizione.

Enumeration.ValueSet è supportato da un BitSet ma non è uno di per sé. Qualcosa sul favorire la composizione.

[Hai sentito dell'erede di una fortuna che ha dato tutto per perseguire il suo amore per la musica? Preferiva la composizione all'eredità. L'ho appena inventato o l'ho ascoltato su Java One?]

Senza dubbio, ValueSet dovrebbe delegare più metodi a BitSet, incluso isEmpty.

Stavo per suggerire di provare values.iterator.isEmpty, ma questo prova solo hasNext che scorre attraverso tutti i possibili valori di controllo per contiene.

https://github.com/scala/scala/blob/v2.11.4/src/library/scala/collection/BitSetLike.scala#L109

se sto leggendo correttamente quello.

L'opzione migliore è e.values.toBitMask forall (_ == 0), che è l'equivalente morale di BitSet.isEmpty.