Parallel for loop

Hi,

On Fri, Apr 18, 2008 at 11:15 AM, Fredrik [email protected] wrote:

I was thinking about that too, but as far as I understand it Ruby only
allows optional arguments to be the last arguments - i.e. the “n”
parameter would have to appear after the code block. And that would
look strange : forkmap{ code }(4).

It’s different with blocks:

irb(main):029:0> def this_that(val=nil)
irb(main):030:1> puts “infinite?” if val.nil?
irb(main):031:1> yield 42
irb(main):032:1> end
=> nil
irb(main):033:0> this_that {|a| p a}
infinite?
42
=> nil
irb(main):034:0> this_that(9) {|a| p a}
42
=> nil
irb(main):035:0>

Arlen

It’s different with blocks:

Ah, I got it! So it should look like this then:

def forkmap(n = nil)
nproc = 0
result = map do |*a|
r, w = IO.pipe
fork do
r.close
w.write( Marshal.dump( yield(*a) ) )
end
if n and (nproc+=1) >= n
Process.wait ; nproc -= 1
end
[ w.close, r ].last
end
Process.waitall
result.map{|r| Marshal.load [ r.read, r.close ].first}
end

irb> Benchmark.realtime {[1,2,3].forkmap{|i| sleep 1 } }
=> 1.01688504219055
irb> Benchmark.realtime {[1,2,3].forkmap(1){|i| sleep 1 } }
=> 3.01162004470825

Thanks! That takes me to another level of Ruby knowledge :slight_smile:

/Fredrik

It’s different with blocks:

(reposting, my last post didn’t appear(?))
Great, thanks for that lesson! It would look like this then.

def forkmap(n = nil)
nproc = 0
result = map do |*a|
r, w = IO.pipe
fork do
r.close
w.write( Marshal.dump( yield(*a) ) )
end
if n and (nproc+=1) >= n
Process.wait ; nproc -= 1
end
[ w.close, r ].last
end
Process.waitall
result.map{|r| Marshal.load [ r.read, r.close ].first}
end

El Viernes, 18 de Abril de 2008, Fredrik
escribió:> end

=> 3.01162004470825
It’s simply great :slight_smile: