Почему Clojure зависает выполнив мои вычисления?

Я экспериментирую с проникающими элементами параллельно. Для каждого элемента я должен выполнить расчет расстояния, чтобы видеть, достаточно ли это близко к целевой точке. Не берите в голову, что структуры данных уже существуют для того, чтобы сделать это, я просто делаю начальные эксперименты на данный момент.

Так или иначе я хотел выполнить некоторые очень простые эксперименты, где я генерирую случайные векторы и фильтрую их. Вот моя реализация, которая делает все это

(defn pfilter [pred coll]
  (map second
    (filter first
      (pmap (fn [item] [(pred item) item]) coll))))

(defn random-n-vector [n]
  (take n (repeatedly rand)))

(defn distance [u v]
  (Math/sqrt (reduce + (map #(Math/pow (- %1 %2) 2) u v))))

(defn -main [& args]
  (let [[n-str vectors-str threshold-str] args
        n (Integer/parseInt n-str)
        vectors (Integer/parseInt vectors-str)
        threshold (Double/parseDouble threshold-str)
        random-vector (partial random-n-vector n)
        u (random-vector)]
    (time (println n vectors 
      (count 
        (pfilter 
          (fn [v] (< (distance u v) threshold))
          (take vectors (repeatedly random-vector))))))))

Код выполняет и возвращает то, что я ожидаю, это - параметр n (длина векторов), векторы (количество векторов) и количество векторов, которые ближе, чем порог к целевому вектору. То, что я не понимаю, - то, почему программы зависают в течение дополнительной минуты перед завершением.

Вот вывод выполнения, которое демонстрирует ошибку

$ time lein run 10 100000 1.0
     [null] 10 100000 12283
     [null] "Elapsed time: 3300.856 msecs"

real    1m6.336s
user    0m7.204s
sys 0m1.495s

Любые комментарии, как отфильтровать параллельно в целом, являются также больше, чем приветствие, поскольку я еще не подтвердил это pfilter на самом деле работы.

14
задан Brian Carper 12 April 2010 в 22:25
поделиться

1 ответ

Вам необходимо вызвать shutdown-agent , чтобы убить потоки, поддерживающие пул потоков, используемый pmap.

Что касается pfilter , он должен работать, но работать медленнее, чем filter , поскольку ваш предикат прост. Распараллеливание не является бесплатным, поэтому вы должны дать каждому потоку умеренно интенсивные задачи, чтобы компенсировать накладные расходы на многопоточность. Сгруппируйте свои товары, прежде чем фильтровать их.

22
ответ дан 1 December 2019 в 12:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: