Я новичок в Clojure, и у меня есть код, который я пытаюсь оптимизировать. Я хочу вычислить количество совпадений. Основная функция - это compute-space, а вывод - это вложенная карта типа
{"w1" {"w11" 10, "w12" 31, ...}
"w2" {"w21" 14, "w22" 1, ...}
...
}
это означает, что "w1" совпадает с "w11" 10 раз и т. д.
Требуется набор документов (предложений) и набор целевых слов, он выполняет итерацию по обоим и, наконец, применяет context-fn, например, скользящее окно, для извлечения контекста- слова. Более конкретно, я закрываю скользящее окно
(compute-space docs (fn [target doc] (sliding-window target doc 5)) targets)
Я тестировал его примерно с 50 миллионами слов (~ 3 миллиона предложений) и примерно. 20000 целей. На создание этой версии уйдет больше суток. Я также написал параллельную функцию pmap (pcompute-space), которая сократила бы время вычислений примерно до 10 часов, но я все же считаю, что она должна быть быстрее. У меня нет другого кода для сравнения, но моя интуиция подсказывает, что он должен быть быстрее.
(defn compute-space
([docs context-fn targets]
(let [space (atom {})]
(doseq [doc docs
target targets]
(when-let [contexts (context-fn target doc)]
(doseq [w contexts]
(if (get-in @space [target w])
(swap! space update-in [target w] (partial inc))
(swap! space assoc-in [target w] 1)))))
@space)))
(defn sliding-window
[target s n]
(loop [todo s seen [] acc []]
(let [curr (first todo)]
(cond (= curr target) (recur (rest todo) (cons curr seen) (concat acc (take n seen) (take n (rest todo))))
(empty? todo) acc
:else (recur (rest todo) (cons curr seen) acc)))))
(defn pcompute-space
[docs step context-fn targets]
(reduce
#(deep-merge-with + %1 %2)
(pmap
(fn [chunk]
(do (tick))
(compute-space chunk context-fn targets))
(partition-all step docs)))
Я профилировал приложение с помощью jvisualvm и обнаружил, что clojure.lang.Cons, clojure.lang.ChunkedCons и clojure.lang.ArrayChunk довольно сильно доминируют в процессе (см. Рисунок). Это, безусловно, связано с тем фактом, что я использую этот двойной цикл duplicq (предыдущие эксперименты показали, что этот способ был быстрее, чем использование map, reduce и т.п., хотя я использовал time для тестирования функций). Я очень благодарен за любую информацию, которую вы могли бы мне предоставить, и за предложения по рефакторингу кода и ускорению его работы. Думаю, здесь могут помочь редукторы, но я не уверен, как и / или почему.
ТЕХНИЧЕСКИЕ ХАРАКТЕРИСТИКИ
MacPro 2010 2,4 ГГц Intel Core 2 Duo 4 ГБ ОЗУ
Clojure 1.6.0
Java 1.7.0_51 Java HotSpot (TM) 64-разрядная серверная виртуальная машина
(partial inc)
по сути то же самое, чтоinc
. - person Shannon Severance   schedule 07.04.2015sliding-window
принимает три аргумента, но только два передаются вcontext-fn
. - person Shannon Severance   schedule 07.04.2015context-fn
это фактически закрытие, переданное вcompute-space
. (fn [цель отправлена] (цель скользящего окна отправлена 5)), например. Я отредактирую вопрос, чтобы прояснить это - person emanjavacas   schedule 07.04.2015