2017-12-05 1 views
0

아래 코드를 벤치 마크하고 비 스레드 버전이 트레드 된 버전보다 빠르게 실행되는 것을 확인하려고합니다. 아래 벤치 마크시 뮤텍스가없는 다중 스레드가 느려짐 (Ruby 2.0, 레일스 4.2.7.1)

 puts Benchmark.measure{ 
     100.times do |i| 
      carrier.services.map do |service_obj| 
      Thread.new { 
       rate << Rate.rate_by_service(service_obj,@package,@from,@to,@credentials) 
      } 
      end.each(&:join) 
     end 
     } 

내가 로그에 관찰

#threading 
4.940000 0.730000 5.670000 ( 5.795008) 
4.740000 0.740000 5.480000 ( 5.554500) 
4.740000 0.730000 5.470000 ( 5.436129) 
4.840000 0.710000 5.550000 ( 5.524418) 
4.710000 0.720000 5.430000 ( 5.431673) 

#no threading 
3.640000 0.190000 3.830000 ( 3.962347) 
3.670000 0.220000 3.890000 ( 4.402259) 
3.430000 0.200000 3.630000 ( 3.780768) 
3.480000 0.190000 3.670000 ( 3.830547) 
3.650000 0.210000 3.860000 ( 4.065442) 

한 가지가 아닌 스레드 버전을 실행할 때, 쿼리의 결과는 아래와 같이 캐시에서 반환 및 스레드 버전이 수행되는 타이밍이다 캐시에서 가져 오지는 않지만 DB에 액세스합니다.

CACHE (0.0ms) SELECT 
    CACHE (0.0ms) SELECT 
    CACHE (0.0ms) SELECT 
    CACHE (0.0ms) SELECT 
    CACHE (0.0ms) SELECT 
    CACHE (0.0ms) SELECT 
    CACHE (0.0ms) SELECT 
    CACHE (0.0ms) SELECT 
    CACHE (0.0ms) SELECT 
    CACHE (0.0ms) SELECT 
    CACHE (0.0ms) SELECT 

참고 : 나는 가독성 목적에 대한 실제 쿼리를 제거했습니다. Caching with Rails # SQL Caching에 따르면

보다 더 느린 비트를 실행하는 스레드 버전의 원인이 될 수있는 것을

누구에 관한 설명시겠습니까 비 스레드

+0

['N + 1' 문제] (https://stackoverflow.com/questions/97197/what-is-n1-select-query-issue)와 유사합니다. 다른 스레드가 동일한 값을 여러 번 읽지 않도록 사전에 필요한 데이터를 프리 페치해야합니다. – mudasobwa

답변

1
  1. ,

    레일 다시 동일한 쿼리가 발생하는 경우 해당 요청에 대해 데이터베이스에 대해 다시 쿼리를 실행하는 것과는 대조적으로 캐시 된 결과 집합을 사용합니다. 쿼리 캐시는 작업 시작시 만들어지며 해당 작업이 끝날 때 소멸되므로 지속 기간 동안 만 지속됩니다. 행동.

  2. ActiveRecord는 스레드 당 하나의 연결을 체크 아웃합니다.

  3. Ruby 구현이 MRI 인 경우 GVL로 인해 CPU 작업이 병렬이 아닙니다. 당신이 액션 내에서 단일 스레드 모드에서 코드를 실행하면

은 그래서, 쿼리 결과는 캐시됩니다. 멀티 스레드 모드에서 코드를 실행하면 각 스레드가 자체 데이터베이스 연결을 획득하고 쿼리 결과가 캐시되지 않으므로 각 스레드가 데이터베이스에 액세스해야하므로 느려질 수 있습니다.

+0

@Aetherus, 고마워요. 내 이해를 깨끗이합니다. 다른 사람들에게도 도움이되기를 바랍니다. –