Wie verbessert man die Textverarbeitungsleistung in Clojure?

8

Ich schreibe eine einfache Desktop-Suchmaschine in Clojure, um mehr über die Sprache zu erfahren. Bis jetzt ist die Leistung während der Textverarbeitungsphase meines Programms wirklich schlecht.

Während der Textverarbeitung muss ich:

  • Bereinige unerwünschte Zeichen;
  • Konvertiert die Zeichenfolge in Kleinbuchstaben;
  • Teilen Sie das Dokument auf, um eine Liste von Wörtern zu erhalten;
  • Erstellen Sie eine Karte, die jedes Wort seinen Vorkommen im Dokument zuordnet.

Hier ist der Code:

%Vor%

Da ich eine andere Implementierung dieses Problems in Haskell habe, habe ich beide verglichen Sie können in den folgenden Ausgaben sehen.

Clojure-Version:

%Vor%

Haskell-Version:

%Vor%

Ich denke, dass die Konvertierung ( string - & gt; Lazy Sequence ) in der Clojure-Implementierung die Performance zerstört. Wie kann ich es verbessern?

PS: Der gesamte Code und die Daten, die in diesen Tests verwendet werden, können hier heruntergeladen werden.

    
luisgabriel 27.04.2013, 21:23
quelle

2 Antworten

4

Einige Dinge, die Sie tun könnten, würden diesen Code wahrscheinlich beschleunigen:

1) Anstatt Ihre chars auf char-val zu mappen, führen Sie einfach direkte Vergleiche zwischen den Zeichen durch. Dies ist schneller aus dem gleichen Grund, es wäre schneller in Java.

2) Sie verwenden wiederholt str , um Einzelzeichenwerte in vollwertige Zeichenfolgen zu konvertieren. Erwägen Sie wiederum, die Zeichenwerte direkt zu verwenden. Auch hier ist die Erstellung von Objekten langsam, genau wie in Java.

3) Sie sollten process-content durch clojure.core/frequencies ersetzen. Vielleicht inspizieren frequencies source, um zu sehen, wie es schneller ist.

4) Wenn Sie eine (hash-map) in einer Schleife aktualisieren müssen, verwenden Sie transient . Siehe: Ссылка

Beachten Sie auch, dass (hash-map) eine PersistentArrayMap zurückgibt, so dass Sie mit jedem Aufruf von update-in neue Instanzen erstellen - daher langsam und warum Sie Transienten verwenden sollten.

5) Das ist dein Freund: (set! *warn-on-reflection* true) - Du hast ziemlich viel darüber nachgedacht, was von profitieren könnte Hinweise

%Vor%     
noahlz 28.04.2013, 02:11
quelle
0

Nur zum Vergleich, hier ist eine Regexp-basierte Clojure-Version

%Vor%     
NielsK 29.04.2013 12:48
quelle