parallelize 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,9 @@
1
+ === 0.3.0 / 2012/06/10
2
+ * Added `pmap`
3
+
4
+ === 0.2.1 / 2011/08/02
5
+ * Compatible to Ruby 1.8
6
+
7
+ === 0.2.0 / 2011/08/02
8
+ * Initial release
9
+
data/Gemfile CHANGED
@@ -7,7 +7,5 @@ source "http://rubygems.org"
7
7
  # Include everything needed to run rake, tests, features, etc.
8
8
  group :development do
9
9
  gem "yard", "~> 0.6.0"
10
- gem "bundler", "~> 1.0.0"
11
10
  gem "jeweler", "~> 1.6.4"
12
- gem "rcov", ">= 0"
13
11
  end
data/Gemfile.lock CHANGED
@@ -6,9 +6,7 @@ GEM
6
6
  bundler (~> 1.0)
7
7
  git (>= 1.2.5)
8
8
  rake
9
- rake (0.9.2)
10
- rcov (0.9.9)
11
- rcov (0.9.9-java)
9
+ rake (0.9.2.2)
12
10
  yard (0.6.8)
13
11
 
14
12
  PLATFORMS
@@ -16,7 +14,5 @@ PLATFORMS
16
14
  ruby
17
15
 
18
16
  DEPENDENCIES
19
- bundler (~> 1.0.0)
20
17
  jeweler (~> 1.6.4)
21
- rcov
22
18
  yard (~> 0.6.0)
data/README.markdown ADDED
@@ -0,0 +1,67 @@
1
+ # parallelize
2
+
3
+ Simple multi-threading for Ruby.
4
+
5
+ ## Installation
6
+ ```
7
+ gem install parallelize
8
+ ```
9
+
10
+ ## Examples
11
+ ```ruby
12
+ require 'rubygems'
13
+ require 'parallelize'
14
+
15
+ parallelize(4) do
16
+ puts "I'm a thread"
17
+
18
+ # ...
19
+ end
20
+
21
+ # Zero-based thread index
22
+ parallelize(4) do |thread_idx|
23
+ puts "I'm thread ##{thread_idx}"
24
+
25
+ # ...
26
+ end
27
+
28
+ # Enumerable#peach
29
+ (0..100).peach(4) do |elem, thread_idx|
30
+ puts "Thread ##{thread_idx} processing #{elem}"
31
+ end
32
+
33
+ # Enumerable#pmap
34
+ (0..100).pmap(4) do |elem|
35
+ elem ** 2
36
+ end
37
+
38
+ (0..100).pmap(8) do |elem, thread_idx|
39
+ elem * thread_idx
40
+ end
41
+ ```
42
+
43
+ ### Collecting exceptions
44
+ ```ruby
45
+ begin
46
+ parallelize(4, true) do |elem, thread_idx|
47
+ # Each thread can complete its block even when some other threads throw exceptions
48
+ end
49
+ rescue ParallelException => e
50
+ p e.exceptions
51
+ end
52
+ ```
53
+
54
+ ## Contributing to parallelize
55
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
56
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
57
+ * Fork the project
58
+ * Start a feature/bugfix branch
59
+ * Commit and push until you are happy with your contribution
60
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
61
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
62
+
63
+ ## Copyright
64
+
65
+ Copyright (c) 2011 Junegunn Choi. See LICENSE.txt for
66
+ further details.
67
+
data/Rakefile CHANGED
@@ -32,13 +32,14 @@ Rake::TestTask.new(:test) do |test|
32
32
  test.verbose = true
33
33
  end
34
34
 
35
- require 'rcov/rcovtask'
36
- Rcov::RcovTask.new do |test|
37
- test.libs << 'test'
38
- test.pattern = 'test/**/test_*.rb'
39
- test.verbose = true
40
- test.rcov_opts << '--exclude "gems/*"'
41
- end
35
+ # TODO: simplecov
36
+ #require 'rcov/rcovtask'
37
+ #Rcov::RcovTask.new do |test|
38
+ # test.libs << 'test'
39
+ # test.pattern = 'test/**/test_*.rb'
40
+ # test.verbose = true
41
+ # test.rcov_opts << '--exclude "gems/*"'
42
+ #end
42
43
 
43
44
  task :default => :test
44
45
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
data/lib/parallelize.rb CHANGED
@@ -6,6 +6,6 @@ require 'parallelize/enumerable_ext'
6
6
  # @param [Fixnum] num_threads Number of concurrent threads
7
7
  # @param [Boolean] collect_exceptions If true, waits for all threads to complete even in case of exception, and throws ParallelException at the end. If false exception is immediately thrown.
8
8
  def parallelize num_threads, collect_exceptions = false, &block
9
- num_threads.times.map.peach(num_threads, collect_exceptions, &block)
9
+ num_threads.times.peach(num_threads, collect_exceptions, &block)
10
10
  end
11
11
 
@@ -1,53 +1,72 @@
1
1
  module Enumerable
2
+ module Parallelize
3
+ def self.it enum, num_threads, method, collect_exceptions, &block
4
+ raise ArgumentError.new("Block not given") unless block_given?
5
+ raise ArgumentError.new("Invalid number of threads") if num_threads < 1
6
+
7
+ threads = []
8
+ enum.each_slice((enum.count{true} / num_threads.to_f).ceil) do |slice|
9
+ threads <<
10
+ case block.arity
11
+ when 2
12
+ Thread.new(slice, threads.length) { |my_slice, thread_idx|
13
+ my_slice.send(method) { |e| yield e, thread_idx }
14
+ }
15
+ when 1
16
+ Thread.new(slice) { |my_slice|
17
+ my_slice.send(method) { |e| yield e }
18
+ }
19
+ when 0, -1
20
+ raise ArgumentError.new("Invalid arity: #{block.arity}") if
21
+ RUBY_VERSION !~ /^1.8\./ && block.arity == -1
22
+ Thread.new(slice) { |my_slice|
23
+ my_slice.send(method) { yield }
24
+ }
25
+ else
26
+ raise ArgumentError.new("Invalid arity: #{block.arity}")
27
+ end
28
+ end
29
+
30
+ exceptions = {}
31
+ threads.each_with_index do |thr, idx|
32
+ begin
33
+ thr.join
34
+ rescue Exception => e
35
+ if collect_exceptions
36
+ exceptions[idx] = e
37
+ nil
38
+ else
39
+ raise e
40
+ end
41
+ end
42
+ end
43
+
44
+ unless exceptions.empty?
45
+ raise ParallelException.new(exceptions)
46
+ end
47
+
48
+ if method == :each
49
+ threads
50
+ elsif method == :map
51
+ threads.map(&:value).inject(:+)
52
+ end
53
+ end
54
+ end
55
+
2
56
  # Divides the Enumerable objects into pieces and execute with multiple threads
3
57
  # @return [Array] Threads.
4
58
  # @param [Fixnum] num_threads Number of concurrent threads
5
59
  # @param [Boolean] collect_exceptions If true, waits for all threads to complete even in case of exception, and throws ParallelException at the end. If false exception is immediately thrown.
6
60
  def peach num_threads, collect_exceptions = false, &block
7
- raise ArgumentError.new("Block not given") unless block_given?
8
- raise ArgumentError.new("Invalid number of threads") if num_threads < 1
61
+ Parallelize.it self, num_threads, :each, collect_exceptions, &block
62
+ end
9
63
 
10
- threads = []
11
- self.each_slice((self.count{true} / num_threads.to_f).ceil) do |slice|
12
- threads <<
13
- case block.arity
14
- when 2
15
- Thread.new(slice, threads.length) { |my_slice, thread_idx|
16
- my_slice.each { |e| yield e, thread_idx }
17
- }
18
- when 1
19
- Thread.new(slice) { |my_slice|
20
- my_slice.each { |e| yield e }
21
- }
22
- when 0, -1
23
- raise ArgumentError.new("Invalid arity: #{block.arity}") if
24
- RUBY_VERSION !~ /^1.8\./ && block.arity == -1
25
- Thread.new(slice) { |my_slice|
26
- my_slice.each { yield }
27
- }
28
- else
29
- raise ArgumentError.new("Invalid arity: #{block.arity}")
30
- end
31
- end
32
-
33
- exceptions = {}
34
- threads.each_with_index do |thr, idx|
35
- begin
36
- thr.join
37
- rescue Exception => e
38
- if collect_exceptions
39
- exceptions[idx] = e
40
- else
41
- raise e
42
- end
43
- end
44
- end
45
-
46
- if exceptions.empty?
47
- threads
48
- else
49
- raise ParallelException.new(exceptions)
50
- end
51
- end
64
+ # Parallelized map.
65
+ # @return [Array] Map function output for each element
66
+ # @param [Fixnum] num_threads Number of concurrent threads
67
+ # @param [Boolean] collect_exceptions If true, waits for all threads to complete even in case of exception, and throws ParallelException at the end. If false exception is immediately thrown.
68
+ def pmap num_threads, collect_exceptions = false, &block
69
+ Parallelize.it self, num_threads, :map, collect_exceptions, &block
70
+ end
52
71
  end
53
72
 
@@ -127,4 +127,14 @@ class TestParallelize < Test::Unit::TestCase
127
127
  (0..100).peach(4) do
128
128
  end
129
129
  end
130
+
131
+ def test_pmap
132
+ thr = 8
133
+ n_per_thr = (101.0 / 8).ceil
134
+ i = -1
135
+ assert_equal(
136
+ (0..100).map { |e, idx| i += 1; "#{e} by #{i / n_per_thr}" },
137
+ (0..100).pmap(thr) { |e, tidx| "#{e} by #{tidx}" }
138
+ )
139
+ end
130
140
  end
metadata CHANGED
@@ -1,114 +1,97 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: parallelize
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
4
5
  prerelease:
5
- version: 0.2.1
6
6
  platform: ruby
7
- authors:
8
- - Junegunn Choi
7
+ authors:
8
+ - Junegunn Choi
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-08-02 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: yard
17
- version_requirements: &id001 !ruby/object:Gem::Requirement
18
- none: false
19
- requirements:
20
- - - ~>
21
- - !ruby/object:Gem::Version
22
- version: 0.6.0
23
- requirement: *id001
24
- prerelease: false
25
- type: :development
26
- - !ruby/object:Gem::Dependency
27
- name: bundler
28
- version_requirements: &id002 !ruby/object:Gem::Requirement
29
- none: false
30
- requirements:
31
- - - ~>
32
- - !ruby/object:Gem::Version
33
- version: 1.0.0
34
- requirement: *id002
35
- prerelease: false
36
- type: :development
37
- - !ruby/object:Gem::Dependency
38
- name: jeweler
39
- version_requirements: &id003 !ruby/object:Gem::Requirement
40
- none: false
41
- requirements:
42
- - - ~>
43
- - !ruby/object:Gem::Version
44
- version: 1.6.4
45
- requirement: *id003
46
- prerelease: false
47
- type: :development
48
- - !ruby/object:Gem::Dependency
49
- name: rcov
50
- version_requirements: &id004 !ruby/object:Gem::Requirement
51
- none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: "0"
56
- requirement: *id004
57
- prerelease: false
58
- type: :development
12
+ date: 2012-06-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: yard
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.6.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.6.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: jeweler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.6.4
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.6.4
59
46
  description: Simple multi-threading for Ruby
60
47
  email: junegunn.c@gmail.com
61
48
  executables: []
62
-
63
49
  extensions: []
64
-
65
- extra_rdoc_files:
66
- - LICENSE.txt
67
- - README.rdoc
68
- files:
69
- - .document
70
- - Gemfile
71
- - Gemfile.lock
72
- - LICENSE.txt
73
- - README.rdoc
74
- - Rakefile
75
- - VERSION
76
- - example/example.rb
77
- - example/example2.rb
78
- - lib/parallelize.rb
79
- - lib/parallelize/enumerable_ext.rb
80
- - lib/parallelize/parallel_exception.rb
81
- - test/helper.rb
82
- - test/test_parallelize.rb
50
+ extra_rdoc_files:
51
+ - LICENSE.txt
52
+ - README.markdown
53
+ files:
54
+ - .document
55
+ - CHANGELOG.rdoc
56
+ - Gemfile
57
+ - Gemfile.lock
58
+ - LICENSE.txt
59
+ - README.markdown
60
+ - Rakefile
61
+ - VERSION
62
+ - example/example.rb
63
+ - example/example2.rb
64
+ - lib/parallelize.rb
65
+ - lib/parallelize/enumerable_ext.rb
66
+ - lib/parallelize/parallel_exception.rb
67
+ - test/helper.rb
68
+ - test/test_parallelize.rb
83
69
  homepage: http://github.com/junegunn/parallelize
84
- licenses:
85
- - MIT
70
+ licenses:
71
+ - MIT
86
72
  post_install_message:
87
73
  rdoc_options: []
88
-
89
- require_paths:
90
- - lib
91
- required_ruby_version: !ruby/object:Gem::Requirement
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
92
77
  none: false
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- hash: 2
97
- segments:
98
- - 0
99
- version: "0"
100
- required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ segments:
83
+ - 0
84
+ hash: 4037532998974082938
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
86
  none: false
102
- requirements:
103
- - - ">="
104
- - !ruby/object:Gem::Version
105
- version: "0"
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
106
91
  requirements: []
107
-
108
92
  rubyforge_project:
109
- rubygems_version: 1.8.6
93
+ rubygems_version: 1.8.24
110
94
  signing_key:
111
95
  specification_version: 3
112
96
  summary: Simple multi-threading for Ruby
113
97
  test_files: []
114
-
data/README.rdoc DELETED
@@ -1,52 +0,0 @@
1
- = parallelize
2
-
3
- Simple multi-threading for Ruby.
4
-
5
- == Installation
6
- gem install parallelize
7
-
8
- == Examples
9
- require 'rubygems'
10
- require 'parallelize'
11
-
12
- parallelize(4) do
13
- puts "I'm a thread"
14
-
15
- # ...
16
- end
17
-
18
- # Zero-based thread index
19
- parallelize(4) do |thread_idx|
20
- puts "I'm thread ##{thread_idx}"
21
-
22
- # ...
23
- end
24
-
25
- # Enumerable#peach
26
- (0..100).peach(4) do |elem, thread_idx|
27
- puts "Thread ##{thread_idx} processing #{elem}"
28
- end
29
-
30
- === Collecting exceptions
31
- begin
32
- parallelize(4, true) do |elem, thread_idx|
33
- # Each thread can complete its block even when some other threads throw exceptions
34
- end
35
- rescue ParallelException => e
36
- p e.exceptions
37
- end
38
-
39
- == Contributing to parallelize
40
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
41
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
42
- * Fork the project
43
- * Start a feature/bugfix branch
44
- * Commit and push until you are happy with your contribution
45
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
46
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
47
-
48
- == Copyright
49
-
50
- Copyright (c) 2011 Junegunn Choi. See LICENSE.txt for
51
- further details.
52
-