Permalink
Browse files

Improve performance of static :import candidate search

Changes:

    - search/available-classes contains a seq of class symbols, not
      strings

    - A new var, search/available-classes-by-last-segment, contains the
      list above grouped by last segment

    - :import static candidate search is now O(1), from O(n)

Every :import candidate search triggered a string/split + compare for
every known static class. Within slamhound for instance, this is 32652
iterations per import.

Reducing each of these to a single map lookup is a significant
performance boost for namespaces that contain many imports.
  • Loading branch information...
1 parent f89415a commit 6f931a17570950c4e2ada2dfe69d7c2c4e758cf6 @guns guns committed Feb 4, 2014
Showing with 12 additions and 10 deletions.
  1. +2 −5 src/slam/hound/regrow.clj
  2. +10 −5 src/slam/hound/search.clj
@@ -88,11 +88,8 @@
"Return a set of class or ns symbols that match the given constraints."
[type missing body]
(case type
- :import (let [m (str missing)
- ss (for [class-name search/available-classes
- :when (= m (last (string/split class-name #"\.")))]
- (symbol class-name))]
- (into (ns-import-candidates missing) ss))
+ :import (into (ns-import-candidates missing)
+ (get search/available-classes-by-last-segment missing))
:alias (set
(for [ns (all-ns)
:let [syms-with-alias (get (ns-qualifed-syms body) missing)]
View
@@ -1,6 +1,7 @@
(ns slam.hound.search
"Search the classpath for vars and classes."
- (:require [clojure.java.io :refer [file reader]])
+ (:require [clojure.java.io :refer [file reader]]
+ [clojure.string :as string])
(:import (java.io BufferedReader File FilenameFilter InputStreamReader
PushbackReader)
(java.util StringTokenizer)
@@ -166,7 +167,11 @@
(reduce #(concat %1 (scan-paths %2)) (scan-paths cp) more)))
(def available-classes
- (remove clojure-fn-file?
- (scan-paths (System/getProperty "sun.boot.class.path")
- (System/getProperty "java.ext.dirs")
- (System/getProperty "java.class.path"))))
+ (->> (scan-paths (System/getProperty "sun.boot.class.path")
+ (System/getProperty "java.ext.dirs")
+ (System/getProperty "java.class.path"))
+ (remove clojure-fn-file?)
+ (map symbol)))
+
+(def available-classes-by-last-segment
+ (group-by #(symbol (peek (string/split (str %) #"\."))) available-classes))

0 comments on commit 6f931a1

Please sign in to comment.