Skip to content

Instantly share code, notes, and snippets.

@jjaffeux
Last active May 26, 2017 14:26
Show Gist options
  • Save jjaffeux/bdf3454eb2f6b21fc98592c4aa9813b7 to your computer and use it in GitHub Desktop.
Save jjaffeux/bdf3454eb2f6b21fc98592c4aa9813b7 to your computer and use it in GitHub Desktop.
benchmark image optim solution
require 'base64'
require 'benchmark'
require 'fileutils'
sample_base64_images = [
"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"
]
images = sample_base64_images.map { |image| Base64.decode64(image) }
def write_image(path, image)
FileUtils.mkdir_p(File.expand_path("..", path))
open(path, "wb") { |file| file << image }
end
def get_dir_filessize(dir)
Dir
.glob(File.join(dir, '**', '*.png'))
.map { |file| File.size(file) }
.inject(:+)
.to_f
end
tests = [
{
name: "pngout -s0",
path: "benchoptimg/pngout_s0",
code: lambda { |path|
images.each.with_index { |image, i|
image_path = "#{path}/#{i}.png"
write_image(image_path, image)
`pngout #{image_path} -s0`
}
}
},
{
name: "zopflipng 20iter",
path: "benchoptimg/zopflipng_20iter",
code: lambda { |path|
images.each.with_index { |image, i|
image_path = "#{path}/#{i}.png"
write_image(image_path, image)
`zopflipng --iterations=20 --splitting=2 --filters=p --lossy_8bit --lossy_transparent -y #{image_path} #{image_path}`
}
}
},
{
name: "zopflipng max",
path: "benchoptimg/zopflipng_max",
code: lambda { |path|
images.each.with_index { |image, i|
image_path = "#{path}/#{i}.png"
write_image(image_path, image)
`zopflipng --iterations=500 --splitting=3 --filters=01234mepb --lossy_8bit --lossy_transparent -y #{image_path} #{image_path}`
}
}
}
]
FileUtils.rm_rf("benchoptimg")
puts "-- Time benchmark"
Benchmark.bm do |x|
x.report("raw") {
FileUtils.mkdir_p("benchoptimg/raw")
images.each.with_index { |image, i| write_image("benchoptimg/raw/#{i}.png", image) }
}
tests.each do |test|
x.report(test[:name]) { test[:code].call(test[:path]) }
end
end
puts "\r\n-- Size benchmark"
no_compression_size = get_dir_filessize("benchoptimg/raw")
test_results = tests.map { |test|
size = get_dir_filessize(test[:path])
difference = (no_compression_size - size) / no_compression_size * 100.0
sign = size < no_compression_size ? "-" : "+"
"#{test[:name]}: #{size} bytes (#{sign}#{difference.abs} %)"
}
puts <<RESULTS
Raw: #{no_compression_size} bytes
#{test_results.join("\r\n")}
RESULTS
@jjaffeux
Copy link
Author

usage ruby test.rb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment