多线程比ruby中的单线程慢

时间:2017-12-05 11:39:46

标签: ruby multithreading ruby-on-rails-3 mutex

我正在尝试对以下代码进行基准测试,

Rate.rate_by_service方法,执行一些DB调用/处理并返回值

mutex = Mutex.new
thread_arr = []
puts Benchmark.measure{
1000.times do |i|
  services.each_with_index do |service_obj,index|
    thread_arr[index] = Thread.new {
      mutex.synchronize {
        rate << Rate.rate_by_service(service_obj,@package,@from,@to,@credentials) #does database calls / calcualtions and returns a value
      }
    }
    #rate << 
  end
  thread_arr.each {|t| t.join}
end
}

我观察到的奇怪之处在于多线程版本比普通版本(没有线程)慢

以下是基准测试结果。

 #threading
 4.870000   0.490000   5.360000 (  6.846712)
 5.300000   0.520000   5.820000 (  7.550946)
 4.640000   0.480000   5.120000 (  6.720078)
 4.580000   0.460000   5.040000 (  6.344415)
 4.510000   0.450000   4.960000 (  6.312238)




#no threading
3.610000   0.240000   3.850000 (  4.088772)
3.360000   0.200000   3.560000 (  3.721254)
3.380000   0.190000   3.570000 (  3.795252)
3.500000   0.200000   3.700000 (  4.156553)
3.580000   0.210000   3.790000 (  4.183601)

我有什么不对劲吗?任何人都可以详细说明为什么会发生这种行为。

我正在使用ruby 2.0,rails Rails 4.2.7.1

1 个答案:

答案 0 :(得分:3)

每个Thread的整个可执行块都被同步,使代码完全同步,但在线程创建和上下文切换上引入了开销。你有什么期望?

要使其异步,应该只同步原始数组更新:

1000.times do |_|
  services.map do |service_obj|
    Thread.new do
      result = Rate.rate_by_service(...)
      mutex.synchronize { rate << result }
    end
  end.each(&:join)
end

请注意,数据库查询Rate.rate_by_service是在互斥锁同步之外进行的。