Многопоточность внутри хеша рубинов - PullRequest
0 голосов
/ 31 августа 2010

У меня есть фрагмент кода, подобный этому

 myhash.each_value{|subhash|
  (subhash['key]'.each {|subsubhash|

     statement that modifies the subsubhash and takes about 0.07 s to execute
     })
  }

Этот цикл выполняется более 100 раз, и, разумеется, он сильно замедляет мое приложение (примерно на 7 секунд до запуска этого цикла).Любые указатели о том, как сделать это быстрее?У меня нет контроля над действительно дорогим заявлением.Есть ли способ, которым я могу использовать несколько потоков в цикле, чтобы операторы могли выполняться параллельно?

Ответы [ 2 ]

0 голосов
/ 31 августа 2010
threads = []
myhash.each_value{ |subhash|
  threads << Thread.start do
    subhash['key'].each { |subsubhash|
     threads << Thread.start do
       statement that modifies the subsubhash and takes about 0.07 s to execute
     end
    }
  end
}
threads.each { |t| t.join }

Обратите внимание, что в MRI 1.8.x используются не реальные потоки, а зеленые, которые не соответствуют реальным потокам ОС.Однако, если вы используете JRuby, вы можете увидеть повышение производительности, поскольку оно поддерживает реальные потоки.

0 голосов
/ 31 августа 2010

Вы можете запустить каждый цикл обработки субхеша в отдельном потоке, но может ли это привести к повышению производительности, может зависеть либо от (1) используемого вами интерпретатора Ruby, либо (2) от того, связан ли самый внутренний блок с IO, либо вычислить переплет.

Причина # 1 в том, что некоторые интерпретаторы Ruby (такие как CRuby / MRI 1.8) используют зеленые потоки , которые обычно не получают никакой выгоды от какой-либо реальной параллельной обработки, даже на многоядерных машинах. Тем не менее, YARV и JRuby оба используют собственные потоки ОС (JRuby даже для 1.8, поскольку JVM использует собственные потоки), поэтому, если вы можете специально нацелить эти интерпретаторы, вы можете увидеть улучшение.

Причина №2 заключается в том, что если внутренний блок связан с вводом-выводом, то даже интерпретатор на основе зеленых потоков может повысить производительность, поскольку большинство ОС хорошо справляются с планированием потоков вокруг блокировки вызовов ввода-вывода. Если блок строго привязан к вычислениям, то только интерпретатор на основе собственных потоков, вероятно, покажет повышение производительности при использовании нескольких потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...