2014-12-24 13 views
6

Ich benutze Scala Enumeration ValueSets in einer ziemlich hohen Durchsatz-Einstellung - Erstellen, Testen, Union'ing und schneiden etwa 10M Sätze/Sekunde/Kern. Ich hatte nicht erwartet, dass dies eine große Sache ist, weil ich irgendwo gelesen hatte, dass sie von BitSets unterstützt wurden, aber überraschenderweise zeigte sich ValueSet.isEmpty als Hotspot in einer Profiling-Sitzung mit YourKit.Scala Enumeration ValueSet.isEmpty langsam

Um zu verifizieren, entschied ich mich zu versuchen, neu zu implementieren, was ich mit dem Java BitSet brauchte, während ich versuchte, einige der Typ-Sicherheit der Verwendung von Scala Enumerations zu behalten. (Die Code-Rezension wurde auf https://codereview.stackexchange.com/questions/74795/scala-bitset-implemented-with-java-bitset-for-use-in-scala-enumerations-to-repl verschoben.) Die gute Nachricht ist, dass die Änderung nur meiner ValueSets zu diesen BitSets tatsächlich 25% meiner Laufzeit einbüßte, also weiß ich nicht, was ValueSet wirklich unter der Haube tut, aber es könnte verbessert werden ...

EDIT: Überprüfung der ValueSet-Quelle scheint anzuzeigen, dass isEmpty definitiv O (N) ist, implementiert mit dem allgemeinen SetLike.isEmpty. Wenn man bedenkt, dass ValueSet mit einem BitSet implementiert ist, ist das ein Fehler?

EDIT: Dies war das Backtrace vom Profiler. Dies scheint eine verrückte Methode zu sein, isEmpty auf einem Bitset zu implementieren.

Backtrace of hot spot in YourKit

+0

"Ich weiß nicht, was ValueSet wirklich unter der Haube macht". Die Quelle ist verfügbar, wenn Sie einen Blick darauf werfen wollten: https://github.com/scala/scala/blob/v2.11.4/src/library/scala/Enumeration.scala#L1 –

+0

Es klingt wie Sie Arbeitscode haben dass Sie Feedback wünschen. Wenn das der Fall ist, sollten Sie Ihre Frage an [codereview.se] verschieben. Ansonsten, bitte, zerstückeln Sie Ihre Frage und machen Sie die eigentliche Frage deutlicher - es hat eine Weile gedauert, bis ich überhaupt gefunden habe, wonach Sie gefragt haben. –

+0

Danke, schau jetzt. Bisher scheint es zu bestätigen, was ich im Profiler gefunden habe (angehängt); Zumindest das ValueSet.isEmpty wird vollständig mit generischen Algorithmen implementiert, wobei es für ein BitSet nicht schwieriger sein sollte als (x == 0). – experquisite

Antwort

1

Für das Protokoll, ich bin alle für unter der Haube suchen, aber dieser Entwurf stellt zu viel von jedem sterblichen Coder.

Die Unsterblichen haben natürlich unendliche Zeit zur Verfügung.

Enumeration.ValueSet wird von einem BitSet unterstützt, ist aber nicht einer selbst. Etwas über die Bevorzugung der Komposition.

[Hast du von dem Erbe eines Glücks gehört, der alles gegeben hat, um seiner Liebe zur Musik nachzugehen? Er bevorzugte Zusammensetzung über Vererbung. Habe ich das gerade erfunden oder habe ich es bei Java One gehört?]

Kein Zweifel, ValueSet sollte mehr Methoden an das BitSet delegieren, einschließlich isEmpty.

Ich würde vorschlagen, versuchen values.iterator.isEmpty, aber das testet nur hasNext, die alle möglichen Werte durchläuft für die Überprüfung nach enthält.

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

Wenn ich lese richtig, dass. Die beste Option ist e.values.toBitMask forall (_ == 0), die das moralische Äquivalent von BitSet.isEmpty ist.