Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class Thing; end
puts '----------------------'

arr = Array.new(100) { Thing.new }
line = ''

arr.each do |el|
GC.start
Expand Down
1 change: 0 additions & 1 deletion benchmark/each_slice_bang_bm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ class Thing; end
puts '----------------------'

arr = Array.new(100) { Thing.new }
line = ''

arr.each_slice(slize_size) do |slice|
GC.start
Expand Down
104 changes: 104 additions & 0 deletions benchmark/hash_each_bang_bm.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
require 'benchmark'
require_relative '../lib/hyper_iterator'

class Key; end
class Val; end

puts '---------------------------------------------------------'
puts '------------------------- each! -------------------------'

puts '---------------------------------------------------------'
puts '------------------ Garbage Collection -------------------'

puts 'Hash#each'
puts '----------------------'

hash = {}
100.times do
hash[Key.new] = Val.new
end

hash.each do |_|
GC.start
print ObjectSpace.each_object(Key).count
print ' '
print ObjectSpace.each_object(Val).count
print ' '
end

puts
puts

puts 'Hash#each!'
puts '----------------------'

hash = {}
100.times do
hash[Key.new] = Val.new
end

hash.each! do |_|
GC.start
print ObjectSpace.each_object(Key).count
print ' '
print ObjectSpace.each_object(Val).count
print ' '
end

puts

puts '---------------------------------------------------------'
puts '-------------------- Objects Created --------------------'


GC.disable
hash = {}
100.times do
hash[Key.new] = Val.new
end

before = ObjectSpace.count_objects
hash.each do |_|
end
after = ObjectSpace.count_objects

puts 'Hash#each'
puts '----------------------'
puts "# of arrays: %d" % (after[:T_ARRAY] - before[:T_ARRAY])
puts "# of nodes: %d" % (after[:T_NODE] - before[:T_NODE])

puts

hash = {}
100.times do
hash[Key.new] = Val.new
end

before = ObjectSpace.count_objects
hash.each! do |el|
end
after = ObjectSpace.count_objects

puts 'Hash#each!'
puts '----------------------'
puts "# of arrays: %d" % (after[:T_ARRAY] - before[:T_ARRAY])
puts "# of nodes: %d" % (after[:T_NODE] - before[:T_NODE])

puts '---------------------------------------------------------'
puts '--------------- Execution Time Comparison ---------------'

GC.enable
n = 10
hash = {}
10_000.times do
hash[Key.new] = Val.new
end

Benchmark.bmbm(7) do |x|
x.report('each!') { n.times { hash.each! { |el| nil } } }
x.report('each') { n.times { hash.each { |el| nil } } }
end

puts '---------------------------------------------------------'

puts
File renamed without changes.
34 changes: 34 additions & 0 deletions benchmark/memory_bm/hash_each.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'benchmark'
require_relative '../../lib/hyper_iterator'
$stdout.sync = true

puts
puts '----------------- Hash#each -----------------'
puts '#i user system total real'

base_hash = {}
1000.times { |i| base_hash["k#{i}"] = '-' * 10 }
hashes = [base_hash]

i = 0
while true
print "#{i} "
hash = {}
report = Benchmark.measure do
hashes[i].each do |k, v|
hash[k.dup] = v.dup
end

# Try to use this line and see how many more iterations you can get
# Remember to uncomment line#24 as well.
# You need to pop the array so the reference goes away.
# arrs[0].each! { |el| arr << el.dup }
end

# Uncomment this to use with the above line#22
# arrs.pop

puts report
hashes << hash
i += 1
end
34 changes: 34 additions & 0 deletions benchmark/memory_bm/hash_each_bang.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'benchmark'
require_relative '../../lib/hyper_iterator'
$stdout.sync = true

puts
puts '----------------- Hash#each! -----------------'
puts '#i user system total real'

base_hash = {}
1000.times { |i| base_hash["k#{i}"] = '-' * 10 }
hashes = [base_hash]

i = 0
while true
print "#{i} "
hash = {}
report = Benchmark.measure do
hashes[i].each! do |k, v|
hash[k.dup] = v.dup
end

# Try to use this line and see how many more iterations you can get
# Remember to uncomment line#24 as well.
# You need to pop the array so the reference goes away.
# arrs[0].each! { |el| arr << el.dup }
end

# Uncomment this to use with the above line#22
# arrs.pop

puts report
hashes << hash
i += 1
end
7 changes: 5 additions & 2 deletions bin/bm
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

docker_command="docker run -m=4m -v `pwd`:`pwd` -w `pwd` hyper_iterator ruby ./benchmark/memory_bm"
if [ "$1" = "each!" ] || [ "$1" = 1 ]; then
eval "$docker_command/each.rb"
eval "$docker_command/each_bang.rb"
eval "$docker_command/array_each.rb"
eval "$docker_command/array_each_bang.rb"
elif [ "$1" = "each_slice!" ] || [ "$1" = 2 ]; then
eval "$docker_command/each_slice.rb"
eval "$docker_command/each_slice_bang.rb"
elif [ "$1" = 3 ]; then
eval "$docker_command/hash_each.rb"
eval "$docker_command/hash_each_bang.rb"
else
echo 'Please specify method for benchmarking. You can choose anyone from below:'
echo '1. each!'
Expand Down
3 changes: 2 additions & 1 deletion lib/hyper_iterator.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require_relative "./hyper_iterator/version"
require_relative "./iterators/each_bang"
require_relative "./iterators/hash_each_bang"
require_relative "./iterators/each_slice_bang"

module HyperIterator
Expand All @@ -14,5 +15,5 @@ def self.each!(iterable)
end

Array.include HyperIterator::EachBang
Hash.include HyperIterator::EachBang
Hash.include HyperIterator::HashEachBang
Array.include HyperIterator
11 changes: 11 additions & 0 deletions lib/iterators/hash_each_bang.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module HyperIterator
module HashEachBang
def each!
each do |pair|
yield pair
self[pair[0]] = nil
end
nil
end
end
end
6 changes: 3 additions & 3 deletions test/iterators/hash_each_bang_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ def test_that_it_yield_block
assert vals == ord_range
end

def test_that_it_remove_elements_from_array_on_the_fly
def test_that_it_sets_all_values_to_nil_on_the_fly
@hash.each! {}
assert @hash.count == 0
assert @hash.values.all?(&:nil?)
end

def test_that_it_returns_nil
Expand Down Expand Up @@ -83,6 +83,6 @@ def test_that_it_can_use_class_method

assert keys_1 == keys_2
assert vals_1 == vals_2
assert hash_2.empty?
assert hash_2.values.all?(&:nil?)
end
end