0

我对 ruby​​ 很陌生,我正在学习如何在多个线程中进行处理。我所做的是使用 Nokogiri 解析一个 170mb 的 xml 文件,并将数据库(Postgresql)插入到我的 .each() 中的一个新线程中。请提出一种更好的方法来处理这个非常大的文件并在多个线程中进行。这是我到目前为止所拥有的。

    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 有一个全局解释器锁,并且一次只能运行一个线程。在 MRI Ruby 中使用线程仅在线程执行 IO 操作(或等待能够这样做)时提高性能,并且程序进度不依赖于这些 IO 操作的结果(因此您不会主动等待它们)。

我建议您在这里停止使用线程,而是计算您希望插入的所有值,然后将它们批量插入。代码也将更容易理解和推理。即使从单个线程中一个一个地插入它们也会更快,但没有理由这样做。

于 2012-05-28T10:07:33.377 回答