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
、それらを同時に開始します (atom を使用)。私が渡す関数は、各スレッドの本体です。
store-data
本文は、キーと値のリストであるという名前のリストに単純にマップされます (例: {:a 1 :b 2}
。現在、コード内のこのリストの長さは 10 です。ユーザーの数も 10 です。
ご覧のとおり、エージェント見送りのコードはコメントアウトされています。これにより、コードが正常に実行されます。ただし、送信を有効にすると、ファイルに書き込まなくても実行時間が遅すぎます。
編集:
彼がエージェントに送信する前に、各スレッドにドットを印刷しました。ドットは見送りがない場合と同じくらい速く表示されます。したがって、最終的には何かがブロックする必要があります。
私は何か間違ったことをしていますか?