我对 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
与单线程情况相比,您正在执行的操作不会导致数据更快地插入到数据库中。MRI Ruby 具有全局解释器锁,一次只能运行一个线程。在 MRI Ruby 中使用线程仅在线程执行 IO 操作(或等待能够执行此操作)时提高性能,并且程序进度不依赖于这些 IO 操作的结果(因此您不会主动等待它们)。
我建议您在此处停止使用线程,而是计算要插入的所有值,然后它们大量插入它们。代码也将更易于理解和推理。即使从单个线程中逐个插入它们也会更快,但没有理由这样做。