Skip to content

Instantly share code, notes, and snippets.

@RyanScottLewis
Created November 7, 2014 13:29
Show Gist options
  • Save RyanScottLewis/d38657cdb1609cf92b1d to your computer and use it in GitHub Desktop.
Save RyanScottLewis/d38657cdb1609cf92b1d to your computer and use it in GitHub Desktop.
require 'thread'
class Enumerator
def in_threads(threads=4, &block)
queue = Queue.new
each { |*args| queue << args }
threads.times.collect do
Thread.new { block.call(*queue.pop) until queue.empty? }
end
end
end
# -----------------------------------------------------------------------------
# Support classes for examples
module HTTP
class File
def body
download if @body.nil?
@body
end
def to_s
body
end
def to_i
body.length
end
protected
def download
sleep(0.05) # Fake downloading here...
@body = 'Fake downloaded content...'
end
end
end
# -----------------------------------------------------------------------------
# Simple usage
require 'benchmark'
Benchmark.bm(15) do |x|
x.report :Unthreaded do
10.times { sleep(0.05) }
end
x.report :Threaded do
10.times.in_threads(10) { sleep(0.05) }.each(&:join)
end
end
# -----------------------------------------------------------------------------
# Simple usage 2
require 'benchmark'
Benchmark.bm(15) do |x|
x.report :Unthreaded do
(1..10).each { |i| sleep(0.05) }
end
x.report :Threaded do
(1..10).each.in_threads(10) { |i| sleep(0.05) }.each(&:join)
end
end
# -----------------------------------------------------------------------------
# Ruby 2.0.0-rc2 Enumerable::Lazy usage
require 'benchmark'
Benchmark.bm(15) do |x|
files = (1..10).collect { |i| HTTP::File.new }
x.report :Unthreaded do
puts
p files.collect(&:to_i)
puts
end
x.report :Threaded do
puts
p files.lazy.collect(&:to_i).in_threads(10).each(&:join)
puts
end
end
require 'thread'
module Enumerable
class Threaded < Enumerator
def initialize(obj=nil)
@queue = Queue.new
super(obj) do |yielder|
obj.each do |item|
end
end
end
def each
Lazy.new(self) do |yielder, val|
yielder << yield(val)
end
end
end
def threaded(threads=4, &block)
queue = Queue.new
each { |*args| queue << args }
threads.times.collect do
Thread.new { block.call(*queue.pop) until queue.empty? }
end
end
end
class Enumerator
end
# -----------------------------------------------------------------------------
# Support classes for examples
module HTTP
class File
def body
download if @body.nil?
@body
end
def to_s
body
end
def to_i
body.length
end
protected
def download
sleep(0.05) # Fake downloading here...
@body = 'Fake downloaded content...'
end
end
end
# -----------------------------------------------------------------------------
# Simple usage
require 'benchmark'
Benchmark.bm(15) do |x|
x.report :Unthreaded do
10.times { sleep(0.05) }
end
x.report :Threaded do
10.times.in_threads(10) { sleep(0.05) }.each(&:join)
end
end
# -----------------------------------------------------------------------------
# Simple usage 2
require 'benchmark'
Benchmark.bm(15) do |x|
x.report :Unthreaded do
(1..10).each { |i| sleep(0.05) }
end
x.report :Threaded do
(1..10).threaded(10).each { |i| sleep(0.05) }.each(&:join)
end
end
# -----------------------------------------------------------------------------
# Ruby 2.0.0-rc2 Enumerable::Lazy usage
# require 'benchmark'
#
# Benchmark.bm(15) do |x|
#
# files = (1..10).collect { |i| HTTP::File.new }
#
# x.report :Unthreaded do
# puts
# p files.collect(&:to_i)
# puts
# end
#
# x.report :Threaded do
# puts
# p files.lazy.collect(&:to_i).in_threads(10).each(&:join)
# puts
# end
#
# end
require 'thread'
class Worker
def execute
sleep rand + 0.01
end
end
thread_count = 12
thread_sleep_time = 0.01
queue = Queue.new
thread_proc = Proc.new do
loop do
queue.empty? ? Thread.current.kill : queue.pop.execute
sleep(thread_sleep_time)
end
end
threads = thread_count.times.collect { Thread.new(&thread_proc) }
50.times { queue << Worker.new }
p Thread.list.count - 1 # => 12 (+1 main thread)
# sleep(0.01) until threads.none?(&:alive?)
threads.each(&:join)
# threads.each(&:kill)
puts "DONE!"
p Thread.list.count # => 1 (main thread)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment