annotations_collection_with_doc.each do |annotations, doc| messages += Annotation.prepare_annotations!(annotations, doc, options) end
Annotation.prepare_annotations!(annotations, doc, options)
の先の処理はテキスト処理でCPUバウンドであることがわかっています。
またannotations_collection_with_doc
は数十であることもわかっています。
そこでつぎのように、入ってきただけバカスカRactorをつくっって並列かしてみました。
Ractor.make_shareable(TextAlignment::CHAR_MAPPING) Ractor.make_shareable(TextAlignment::LCSMin::PLACEHOLDER_CHAR) ractors = annotations_collection_with_doc.collect do |annotations, doc| r = Ractor.new do a, d, o = Ractor.receive m = Annotation.prepare_annotations!(a, d, o) Ractor.yield [m, a] end r.send [annotations, doc.dup, options] [r, doc] end annotations_collection_with_doc = ractors.each do |r, doc| error_messages, annotations = r.take messages += error_messages [annotations, doc] end
ざっくり見たかんじでは2倍ぐらいの速度では動きました。 4コアあるので、理想的には4倍の速さになって欲しいです。 スレッドを立てすぎて遅いのか、Ractor間のデータのやりとりで遅いのかは謎です。
たぶんキュー作ってワーカーモデルで、並列数を制限すればいいんですけど、面倒臭いですよね。 なるほどー、MaNyでRactorとネイティブスレッドがM:Nで動いてほしいです。
https://github.com/grosser/parallel を使ったら簡単に並列数を制限できるのでしょうか?