Я пишу тест для программы в Clojure. У меня есть n
потоки, одновременно обращающиеся к кешу. Каждый поток будет обращаться к кешу x
раз. Каждый запрос должен быть зарегистрирован в файле.
С этой целью я создал агент, который хранит путь к файлу для записи. Когда я хочу написать, я send-off
использую функцию, которая записывает в файл и просто возвращает путь. Таким образом, мои записи файлов не содержат условий гонки.
Когда я выполняю свой код без агента, он завершается через несколько миллисекунд. Когда я использую агент и прошу каждый поток отправлять агенту каждый раз, когда мой код работает ужасно медленно. Я говорю минуты.
(defn load-cache-only [usercount cache-size]
"Test requesting from the cache only."
; Create the file to write the benchmark results to.
(def sink "benchmarks/results/load-cache-only.txt")
(let [data-agent (agent sink)
; Data for our backing store generated at runtime.
store-data (into {} (map vector (map (comp keyword str)
(repeat "item")
(range 1 cache-size))
(range 1 cache-size)))
cache (create-full-cache cache-size store-data)]
(barrier/run-with-barrier (fn [] (load-cache-only-work cache store-data data-agent)) usercount)))
(defn load-cache-only-work [cache store-data data-agent]
"For use with 'load-cache-only'. Requests each item in the cache one.
We time how long it takes for each request to be handled."
(let [cache-size (count store-data)
foreachitem (fn [cache-item]
(let [before (System/nanoTime)
result (cache/retrieve cache cache-item)
after (System/nanoTime)
diff_ms ((comp str float) (/ (- after before) 1000))]
;(send-off data-agent (fn [filepath]
;(file/insert-record filepath cache-size diff_ms)
;filepath))
))]
(doall (map foreachitem (keys store-data)))))
Код (barrier/run-with-barrier)
просто порождает usercount
потоков и запускает их одновременно (используя атом). Функция, которую я передаю, является телом каждого потока.
Тело будет просто отображать список с именем store-data
, который является списком ключ-значение (например, {:a 1 :b 2}
. Длина этого списка в моем коде прямо сейчас составляет 10. Количество пользователей также равно 10.
Как видите, код отправки агента закомментирован. Это заставляет код выполняться нормально. Однако, когда я включаю отправку, даже без записи в файл, время выполнения слишком медленное.
Редактировать:
Я заставил каждую ветку, прежде чем он отправится к агенту, поставить точку. Точки появляются так же быстро, как и без проводов. Так что должно быть что-то блокирующее в конце.
Я делаю что-то неправильно?