Доброго времени суток.
Разбираюсь с топиком.
Написал простенький тест, где в цикле несколько раз обрабатывается одна и та же функция со слипом в 1000мс, надеясь что распаралелив, я получу общее время выполнения чуть более 1с. Максимальное количество вызовов 1000.
Применяя блокирующие !!> <!! я этого добился. Накладные расходы в 40-50 мс хоть и больше чем аналогичный теста на Erlang, ну да ладно. Ведь там "зеленые нити", а на сколько я понял из документации, не блокирующие операции в пределах блока go как раз и должны выполняться в пуле "зеленых потоков".
Но не тут то было.
Вот примеры выолнения на моей машине (4 ядра).
(time (<!! (schedule (take 50 funcs))))
"Elapsed time: 1007.054 msecs"
И тут начинает работать к-то "магический множитель"
(time (<!! (schedule (take 51 funcs))))
"Elapsed time: 2001.601 msecs"
(time (<!! (schedule (take 1000 funcs))))
"Elapsed time: 20087.742 msecs"
Вот пример кода:
(defn schedule [functions]
(let [total (count functions)
chans (chan)
]
(doseq [f functions]
(go (>! chans (f))))
(go (loop [i 0 ret []]
(if (= i total)
ret
(recur (inc i) (conj ret (alt! [chans] ([v] v))))
)))
))
Скорее всего я чего-то не понимаю и не дочитал. Заранее благодарен за любую помощь.