0

私はRubyが初めてで、複数のスレッドでプロセスを実行する方法を学んでいます。Nokogiri を使用して 170 MB の xml ファイルを解析し、.each() 内の新しいスレッド内にデータベース (Postgresql) 挿入を配置しています。この非常に大きなファイルを処理し、複数のスレッドで実行するためのより良いアプローチを提案してください。これが私がこれまでに持っているものです。

    conn = PGconn.connect("localhost", 5432, "", "", "oaxis","postgres","root")

    f = File.open("metadata.xml")
    doc = Nokogiri::XML(f)

    counter = 0

    threadArray = []

    doc.xpath('//Title').each do |node|
        threadArray[counter] = Thread.new{
        titleVal = node.text
        random_string = (0...10).map{ ('a'..'z').to_a[rand(26)] }.join

        conn.prepare('ins'+random_string, 'insert into sample_tbl (title) values ($1)')
        conn.exec_prepared('ins'+random_string, [titleVal])

        puts titleVal+" ==>"+random_string+ " \n"

        counter += 1
       }

    end

threadArray.each {|t| t.join}

f.close
4

1 に答える 1

1

あなたがしていることは、シングルスレッドの場合と比較して、データがデータベースに高速に挿入されるという結果にはなりません。MRI Ruby にはグローバル インタープリター ロックがあり、一度に 1 つのスレッドしか実行されません。MRI Ruby でスレッドを使用すると、スレッドが IO アクションを実行している (または実行できるようになるのを待っている) 場合にのみパフォーマンスが向上し、プログラムの進行状況はそれらの IO アクションの結果に依存しません (したがって、積極的に待機する必要はありません)。

ここでスレッドの使用をやめ、代わりに挿入したいすべての値を計算し、それらをまとめて挿入することをお勧めします。コードも理解しやすく、推論も簡単になります。1 つのスレッドから 1 つずつ挿入するだけでも高速ですが、そうする理由はありません。

于 2012-05-28T10:07:33.377 に答える