У меня есть последовательность клиентов, которую нужно обрабатывать параллельно. Я пытался использовать pmap
для этого. Результат мучительно медленный, намного медленнее, чем последовательная реализация. Внутренняя функция process-customer
имеет транзакцию. Очевидно, что pmap запускает все транзакции сразу, и в итоге они повторно пытаются убить производительность. Каков наилучший способ распараллелить это?
(defn process-customers [customers]
(doall
(pmap
(fn [sub-customers]
(doseq [customer sub-customers]
(process-customer customer)))
(partition-all 10 customers))))
EDIT: функция process-customer
включает следующие шаги. Я пишу шаги для краткости. Все шаги находятся внутри транзакции, чтобы гарантировать, что другая параллельная транзакция не вызовет несоответствий, таких как отрицательный запас.
(defn- process-customer [customer]
"Process `customer`. Consists of three steps:
1. Finding all stores in which the requested products are still available.
2. Sorting the found stores to find the cheapest (for the sum of all products).
3. Buying the products by updating the `stock`.
)
РЕДАКТИРОВАТЬ 2: приведенная ниже версия process-customers
имеет такую же производительность, как параллельная версия process-customers
выше. Ниже, очевидно, последовательно.
(defn process-customers [customers]
"Process `customers` one by one. In this code, this happens sequentially."
(doseq [customer customers]
(process-customer customer)))
stock
, который должен быть согласованным, кажется узким местом. - person Gakuo   schedule 30.04.2019partition-all
? И мое следующее решение, когдаpmap
просто недостаточно хорошо, обычно это reducers. - person Stefan Kamphausen   schedule 30.04.2019