tags:

views:

32

answers:

2

I have a code snippet like this

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

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

This loop runs 100+ times and needless to say slows down my application tremendously(about 7 seconds to run this loop).

Any pointers on how to make this faster? I have no control over the really expensive statement. Is there a way I can multi thread within the loop so the statements can be executed in parallel?

A: 

You could run each subhash processing loop in a separate thread but whether or not this results in a performance boost may depend on either (1) the Ruby interpreter you are using or (2) whether the innermost block is IO-bound or compute-bound.

The reason for #1 is that some Ruby interpreters (such as CRuby/MRI 1.8) use green threads which typically do not benefit from any actual parallel processing, even on multicore machines. However, YARV and JRuby both use native OS threads (JRuby even for 1.8 since the JVM uses native threads), so if you can target those interpreters specifically then you might see an improvement.

The reason for #2 is that if the innermost block is IO-bound then even a green thread based interpreter might improve performance since most OSes do a good job of scheduling threads around blocking IO calls. If the block is strictly compute-bound then only a native-thread based interpreter will likely show a performance boost using multiple threads.

maerics
A: 
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 }

Note that MRI 1.8.x doesn't use real threads, but rather green ones which do not correspond to real OS threads. However, if you use JRuby you might see a performance boost as it supports real threads.

Mahmoud
You need a Thread.join in there somewhere to ensure all the threads complete. You also need to worry about this being thread safe, i.e. does "statement that modifies the subhash..." use any other hash keys in it's computation?
Jason Noble
I mentioned that he needs to do a join in my initial post, but I added the code in there just for you :P. As for thread safeness, I guess it's up to the OP to decide weather it's a problem or not since I can't tell by his pseudocode.
Mahmoud
Thanks all for the suggestions. I tried this, and like all of you said , I could not really get much out of it. Blame it on the interpreter.
rubyer