Skip to content

Instantly share code, notes, and snippets.

@sferik
Created March 1, 2014 02:44
Show Gist options
  • Save sferik/9284252 to your computer and use it in GitHub Desktop.
Save sferik/9284252 to your computer and use it in GitHub Desktop.
def pmap(enum)
return to_enum(:pmap, enum) unless block_given?
enum.map { |e| Thread.new { yield e } }.map(&:value)
end
# Returns elements in order, as expected.
pmap(1..10) { |e| e } #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Returns elements in nondeterministic order on MRI >= 1.9.3.
# Works as expected on JRuby, Rubinius, and earlier versions of MRI.
pmap(1..10).to_a #=> [7, 2, 3, 4, 6, 5, 9, 8, 10, 1]
@sferik
Copy link
Author

sferik commented Mar 1, 2014

@mkdynamic @cromwellryan That makes sense. Thanks for explaining.

In case anyone else is curious, this is how I was able to get the correct ordering for pmap:

def pmap_with_index(enum)
  return to_enum(:pmap_with_index, enum) unless block_given?
  enum.map.with_index { |e, i| Thread.new { yield e, i } }.map(&:value)
end

def pmap(enum)
  return to_enum(:pmap, enum) unless block_given?
  pmap_with_index(enum).sort_by { |_, i| i }.map{ |e, _| yield e } 
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment