Created
October 2, 2014 21:46
-
-
Save xunker/06571aec238e0c54ca4d to your computer and use it in GitHub Desktop.
Compare zipruby memory consumption with others
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/user/bin/env ruby | |
# | |
# Demonstrates memory behaviour with zipruby vs rubyzip vs exec('unzip'). | |
# Tested with mri 1.8.7/1.9.3/2.1.2, zipruby 0.3.6 and rubyzip 1.1.6. | |
# | |
# Usage: ruby zipruby_test.rb <test method> | |
# | |
# Test methods are: | |
# read_zipruby read file from zip using zipruby gem | |
# read_rubyzip read file from zip using rubyzip gem | |
# read_exec read files from zip using exec + unzip(1) | |
# data_times (sanity) populate var using String#* to size of test file | |
# data_append (sanity) populate var using String#<< to size of test file | |
# | |
# Code assumes you have unzip(1L), curl(1) and BSD-style ps(1). | |
# | |
# This script does an action 10,000 times, stopping every 1,000 times to | |
# record its own memory. At the end of the run it prints all 10 memory | |
# footprints in the order they were recorded. | |
# | |
# Results: | |
# | |
# read_zipruby | |
# ruby-1.8.7: 56K, 110K, 161K, 208K, 257K, 306K, 357K, 403K, 451K, 499K | |
# ruby-1.9.3: 60K, 112K, 167K, 214K, 262K, 312K, 362K, 409K, 456K, 506K | |
# ruby-2.1.2: 72K, 136K, 194K, 258K, 311K, 371K, 412K, 473K, 527K, 587K | |
# | |
# read_rubyzip | |
# ruby-1.8.7: requires >= 1.9.2 | |
# ruby-1.9.3: 14K, 20K, 20K, 21K, 21K, 21K, 21K, 23K, 23K, 23K | |
# ruby-2.1.2: 21K, 26K, 27K, 27K, 28K, 28K, 30K, 30K, 30K, 30K | |
# | |
# read_exec | |
# ruby-1.8.7: 5K, 5K, 5K, 5K, 5K, 5K, 5K, 5K, 5K, 5K | |
# ruby-1.9.3: 7K, 8K, 8K, 8K, 8K, 8K, 8K, 8K, 8K, 8K | |
# ruby-2.1.2: 23K, 27K, 30K, 30K, 31K, 31K, 31K, 31K, 31K, 31K | |
# | |
# data_times | |
# ruby-1.8.7: 11K, 19K, 19K, 19K, 19K, 19K, 19K, 19K, 27K, 27K | |
# ruby-1.9.3: 18K, 19K, 25K, 29K, 36K, 41K, 43K, 49K, 49K, 51K | |
# ruby-2.1.2: 21K, 33K, 42K, 49K, 55K, 55K, 55K, 62K, 71K, 71K | |
# | |
# data_append | |
# ruby-1.8.7: 3K, 3K, 3K, 3K, 3K, 3K, 3K, 3K, 3K, 3K | |
# ruby-1.9.3: 6K, 6K, 6K, 6K, 7K, 7K, 7K, 7K, 7K, 7K | |
# ruby-2.1.2: 18K, 25K, 31K, 36K, 38K, 42K, 45K, 48K, 49K, 50K | |
require 'rubygems' # for testing under <= 1.8.7 | |
url = 'https://epub-samples.googlecode.com/files/mymedia_lite-20130621.epub' | |
file = './mymedia_lite-20130621.epub' | |
page = 'OEBPS/text/book_0002.xhtml' # file from zip above | |
page_size = 13_103 # size of page file above | |
unless File.exists?(file) | |
puts "Downloading test epub: #{url}" | |
`/usr/bin/env curl #{url} > #{file}` | |
end | |
class TestClass | |
def initialize(file_path, page_path, page_size) | |
@file_path = file_path | |
@page_path = page_path | |
@page_size = page_size | |
end | |
def data_times | |
('x' * @page_size) | |
end | |
def data_append | |
''.tap { |d| @page_size.times { d << 'x' } } | |
end | |
def read_zipruby | |
Zip::Archive.open(@file_path) {|zip| | |
zip.fopen(@page_path).read | |
} | |
end | |
def read_rubyzip | |
Zip::File.open(@file_path) do |zip| | |
zip.glob(@page_path).first.get_input_stream.read | |
end | |
end | |
def read_exec | |
`/usr/bin/env unzip -p #{@file_path} #{@page_path}` | |
end | |
end | |
method_list = %w[ read_zipruby read_rubyzip read_exec data_times data_append ] | |
method_name = ARGV[0] | |
raise(["provide method name: ", method_list.join(', ') ].join) unless | |
method_list.include?(method_name) | |
case method_name | |
when 'read_zipruby' | |
require 'zipruby' # 0.3.6 | |
when 'read_rubyzip' | |
require 'zip' # rubyzip 1.1.6 | |
end | |
memory_stats = [] | |
1.upto(10_000) do |i| | |
print '.' | |
x = TestClass.new(file, page, page_size).send(method_name.to_sym) | |
raise "Size mismatch: #{x.to_s.bytesize} != #{page_size}" unless | |
x.to_s.bytesize == page_size | |
if i % 1_000 == 0 | |
print "#{i} " | |
sleep(0.5) # Give time for GC to come in. | |
mem = (`/usr/bin/env ps -o rss -p #{$$}`.strip.split.last.to_i/1000).to_s + 'K' | |
puts mem | |
memory_stats << mem | |
end | |
end | |
puts "\n#{method_name}: #{memory_stats.join(', ')}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment