GCの影響は少なそう - @ledsun blog で、コピーする範囲を小さくすることで高速化できそうと考えました。 そこで、根本的にRactor化する範囲を小さくします。 そうすることでRactorで受け渡しするデータを最小化し、なんならmoveします。
次のようなソースコードにしました。
pipe = Ractor.new do loop do Ractor.yield Ractor.receive end end workers = (1..4).map do Ractor.new pipe do |pipe| while msg = pipe.take begin aligner = TextAlignment::TextAlignment.new(msg[:ref_text], msg[:options]) aligner.align(msg[:text], msg[:denotations] + msg[:blocks]) Ractor.yield(Ractor.make_shareable({ index: msg[:index], denotations: aligner.transform_hdenotations(msg[:denotations]), blocks: aligner.transform_hdenotations(msg[:blocks]), lost_annotations: aligner.lost_annotations, block_alignment: aligner.block_alignment }), move: true) rescue => e Ractor.yield(Ractor.make_shareable({ error: e })) end end end end annotations_collection_with_doc.each do |annotations, doc| ref_text = doc&.original_body || doc.body results = {} targets = annotations.filter {|a| a[:denotations].present? || a[:blocks].present? } targets.each_with_index do |annotation, index| # align_hdenotations text = annotation[:text] denotations = annotation[:denotations] || [] blocks = annotation[:blocks] || [] pipe.send(Ractor.make_shareable({ index: index, ref_text: ref_text, text: text, denotations: denotations, blocks: blocks, options: options }), move: true) end.each do |annotation| _r, result = Ractor.select(*workers) if result[:error] raise "[#{annotation[:sourcedb]}:#{annotation[:sourceid]}] #{result[:error].message}" else results[result[:index]] = result end end messages << targets.map.with_index do |annotation, index| result = results[index] annotation[:denotations] = result[:denotations] annotation[:blocks] = result[:blocks] annotation[:text] = ref_text annotation.delete_if{|k,v| !v.present?} if result[:lost_annotations].present? { sourcedb: annotation[:sourcedb], sourceid: annotation[:sourceid], body:"Alignment failed. Invalid denotations found after transformation", data:{ block_alignment: result[:block_alignment], lost_annotations: result[:lost_annotations] } } else nil end end.compact end
これで速くなるはずです。 うごかしてみます。
比較のためにRactorを使わない時の結果を載せます。
2m14s -> 7m 41s です。 とても遅くなりました。
え?そんなことあるの?