通常我们一个接一个地迭代数组:
a = [1, 2, 3, 4]
b = []
a.each do |x|
b << x * 5
end
b = [5, 10, 15, 20]如果我不关心数组中内容的顺序,但希望通过并发运行乘法操作来提高迭代速度,该怎么办?例如,这样的结果是可以接受的:
b = [15, 10, 5, 20] # or
b = [5, 20, 15, 10] # or
b = [20, 15, 5, 10]我该怎么做?
发布于 2013-09-27 01:42:20
由于GIL的存在,MRI并不能实现真正的多核并行;线程并不能让你在受CPU限制的任务上获得真正的性能提升(尽管它确实能在受IO限制的任务上带来性能提升);您需要运行JRuby或Rubinius才能获得受CPU限制的任务的并行性,因为它们实际上可以同时跨多个内核分配工作。
也就是说,假设您正在运行一个提供真正并行性的VM:
b = a.map {|x|
Thread.new {
Thread.current[:out] = x * 5
}
}.map {|t| t.join; t[:out] }(这段代码非常难看,应该根据实际使用情况进行重构。它还将按照创建线程的顺序返回结果,同时仍然并行化任务。)
这里的要点是1)在线程局部变量中传播返回值(这样你就不必对共享值执行possibly-unatomic operation;如果你想这样做,你需要引入一个互斥锁),2)在创建的每个线程上调用#join,这样我们就可以确保创建的每个线程都已经完成运行。
https://stackoverflow.com/questions/19034523
复制相似问题