2015-08-18 23:26:03 +00:00
|
|
|
require 'bundler/setup'
|
2014-05-01 18:54:25 +00:00
|
|
|
require 'timeout'
|
2014-05-25 22:31:03 +00:00
|
|
|
require 'stringio'
|
2015-08-18 23:27:01 +00:00
|
|
|
require 'oga'
|
2014-04-29 11:38:56 +00:00
|
|
|
|
2014-05-01 18:54:25 +00:00
|
|
|
Thread.abort_on_exception = true
|
|
|
|
|
2014-04-29 11:38:56 +00:00
|
|
|
##
|
2014-05-11 19:15:33 +00:00
|
|
|
# Returns memory usage in bytes. If /proc exists it is used, otherwise it falls
|
|
|
|
# back to `ps`.
|
2014-04-29 11:38:56 +00:00
|
|
|
#
|
|
|
|
# @return [Fixnum]
|
|
|
|
#
|
|
|
|
def memory_usage
|
2014-05-11 19:15:33 +00:00
|
|
|
if File.exists?('/proc')
|
|
|
|
kb = File.read('/proc/self/status').match(/VmRSS:\s+(\d+)/)[1].to_i
|
|
|
|
else
|
|
|
|
kb = `ps -o rss= #{Process.pid}`.strip.to_i
|
|
|
|
end
|
|
|
|
|
|
|
|
return kb * 1024
|
2014-04-29 11:38:56 +00:00
|
|
|
end
|
|
|
|
|
2014-05-25 22:31:03 +00:00
|
|
|
##
|
|
|
|
# Returns a File instance pointing to the sample XML file.
|
|
|
|
#
|
|
|
|
# @return [File]
|
|
|
|
#
|
|
|
|
def big_xml_file
|
|
|
|
path = File.expand_path('../../benchmark/fixtures/big.xml', __FILE__)
|
|
|
|
|
|
|
|
return File.open(path, 'r')
|
|
|
|
end
|
|
|
|
|
2014-04-29 11:38:56 +00:00
|
|
|
##
|
|
|
|
# Reads a big XML file and returns it as a String.
|
|
|
|
#
|
|
|
|
# @return [String]
|
|
|
|
#
|
|
|
|
def read_big_xml
|
2014-05-25 22:31:03 +00:00
|
|
|
return big_xml_file.read
|
2014-04-29 11:38:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
##
|
2014-05-01 18:54:25 +00:00
|
|
|
# Runs the specified block for at least N seconds while profiling memory usage
|
|
|
|
# at semi random intervals.
|
2014-04-29 11:38:56 +00:00
|
|
|
#
|
|
|
|
# @param [String] name The name of the samples file.
|
2014-05-01 18:54:25 +00:00
|
|
|
# @param [String] duration The amount of seconds to run.
|
2014-04-29 11:38:56 +00:00
|
|
|
#
|
2014-05-01 19:47:51 +00:00
|
|
|
def profile_memory(name, duration = 60)
|
2014-05-01 18:54:25 +00:00
|
|
|
monitor = true
|
|
|
|
threads = []
|
|
|
|
|
|
|
|
threads << Thread.new do
|
|
|
|
puts 'Starting sampler...'
|
|
|
|
|
2014-04-29 11:38:56 +00:00
|
|
|
path = File.expand_path("../samples/#{name}.txt", __FILE__)
|
|
|
|
handle = File.open(path, 'w')
|
|
|
|
handle.sync = true
|
2014-05-01 19:26:05 +00:00
|
|
|
start_time = Time.now
|
2014-04-29 11:38:56 +00:00
|
|
|
|
2014-05-01 18:54:25 +00:00
|
|
|
while monitor
|
|
|
|
usage = memory_usage
|
|
|
|
usage_mb = (usage / 1024 / 1024).round(2)
|
2014-05-01 19:26:05 +00:00
|
|
|
runtime = Time.now - start_time
|
2014-05-01 18:54:25 +00:00
|
|
|
|
2014-05-01 19:26:05 +00:00
|
|
|
handle.write("#{runtime} #{usage}\n")
|
2014-05-01 18:54:25 +00:00
|
|
|
|
2014-05-01 19:26:05 +00:00
|
|
|
puts "#{usage_mb} MB"
|
2014-05-01 18:54:25 +00:00
|
|
|
|
|
|
|
sleep(rand)
|
|
|
|
end
|
|
|
|
|
|
|
|
puts 'Stopping sampler...'
|
|
|
|
|
|
|
|
handle.close
|
|
|
|
end
|
2014-04-29 11:38:56 +00:00
|
|
|
|
2014-05-01 18:54:25 +00:00
|
|
|
threads << Thread.new do
|
|
|
|
start = Time.now
|
|
|
|
|
|
|
|
begin
|
|
|
|
Timeout.timeout(duration) { loop { yield} }
|
|
|
|
rescue Timeout::Error
|
|
|
|
diff = Time.now - start
|
|
|
|
monitor = false
|
|
|
|
|
|
|
|
puts "Finished running after #{diff.round(3)} seconds"
|
2014-04-29 11:38:56 +00:00
|
|
|
end
|
|
|
|
end
|
2014-05-01 18:54:25 +00:00
|
|
|
|
|
|
|
threads.each(&:join)
|
2014-04-29 11:38:56 +00:00
|
|
|
end
|