多线程与一个线程的Ruby性能

and*_*ert 5 ruby concurrency performance multithreading

我正在编写一个程序,将四个XML文件中的数据加载到四个不同的数据结构中.它有这样的方法:

def loadFirst(year)
  File.open("games_#{year}.xml",'r') do |f|
    doc = REXML::Document.new f
    ...
  end
end
def loadSecond(year)
  File.open("teams_#{year}.xml",'r') do |f|
    doc = REXML::Document.new f
    ...
  end
end

etc...
Run Code Online (Sandbox Code Playgroud)

我最初只使用了一个线程并且一个接一个地加载了一个文件

def loadData(year)
  time = Time.now
  loadFirst(year)
  loadSecond(year)
  loadThird(year)
  loadFourth(year)
  puts Time.now - time
end
Run Code Online (Sandbox Code Playgroud)

然后我意识到我应该使用多个线程.我的期望是,从一个单独的线程上的每个文件加载将非常接近所有顺序执行它的速度的四倍(我有一个带有i7处理器的MacBook Pro):

def loadData(year)
  time = Time.now
  t1 = Thread.start{loadFirst(year)}
  t2 = Thread.start{loadSecond(year)}
  t3 = Thread.start{loadThird(year)}
  loadFourth(year)
  t1.join
  t2.join
  t3.join
  puts Time.now - time
end
Run Code Online (Sandbox Code Playgroud)

我发现使用多个线程的版本实际上比另一个慢.这怎么可能?差异大约是20秒,每次大约需要2到3分钟.

线程之间没有共享资源.每个都打开一个不同的数据文件,并将数据加载到与其他数据不同的数据结构中.

SDp*_*SDp 3

我认为(但我不确定)问题是您正在读取(使用多个线程)放置在同一磁盘上的内容,因此所有线程无法同时运行,因为它们等待 IO(磁盘)。

几天前,我不得不做类似的事情(但从网络获取数据),顺序与线程之间的差异是巨大的。

一种可能的解决方案是加载所有文件内容,而不是像在代码中那样加载它。在您的代码中,您逐行读取内容。如果加载所有内容然后处理它,您应该能够执行得更好(因为线程不应该等待 IO)