我正在编写一个程序,将四个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...
我最初只使用了一个线程,然后加载了一个文件:
def loadData(year)
time = Time.now
loadFirst(year)
loadSecond(year)
loadThird(year)
loadFourth(year)
puts Time.now - time
end
然后我意识到我应该使用多个线程。我的期望是,从一个单独的线程上的每个文件加载的速度将是顺序执行的四倍(我有一台配备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
我发现使用多个线程的版本实际上比另一个慢。这怎么可能?差异大约为20秒,每次约需2到3分钟。
线程之间没有共享资源。每个都打开一个不同的数据文件,并将数据加载到与其他数据结构不同的数据结构中。
答案 0 :(得分:3)
我认为(但我不确定)问题是您正在读取(使用多个线程)放在同一磁盘上的内容,因此所有线程都无法同时运行,因为它们等待IO(磁盘)。
前几天我不得不做类似的事情(但从网络中获取数据),顺序与线程之间的区别很大。
一种可能的解决方案是加载所有文件内容,而不是像在代码中那样加载它。在您的代码中,您逐行阅读内容。如果你加载所有内容然后处理它你应该能够更好地执行(因为线程不应该等待IO)
答案 1 :(得分:0)
对于没有更多信息的并行问题比顺序问题慢的原因,我们不可能给出一个结论性的答案,但有一种可能性是:
使用顺序程序,您的磁盘将寻找第一个文件,全部读取,寻找第二个文件,全部读取,等等。
使用并行程序,磁盘头不断地来回移动,试图为来自所有4个线程的I / O请求提供服务。
我不知道是否有办法测量您系统上的磁盘寻道时间:如果是,您可以确认这个假设是否属实。