blob: 6e46544a53d259b90884173591390cb8f9973c85 [file] [edit]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Benchmarks in-memory compression and decompression of an input file,
// comparing zlib and snappy.
#include <memory>
#include <string>
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/time/time.h"
#include "third_party/snappy/src/snappy.h"
#include "third_party/zlib/google/compression_utils.h"
namespace {
void LogThroughputAndLatency(size_t size,
int repeats,
base::TimeTicks tick,
base::TimeTicks tock) {
size_t total_size = size * repeats;
double elapsed_us = (tock - tick).InMicrosecondsF();
double throughput = total_size / elapsed_us;
double latency_us = elapsed_us / repeats;
LOG(INFO) << " Throughput = " << throughput << "MB/s";
LOG(INFO) << " Latency (size = " << size << ") = " << latency_us << "us";
LOG(INFO) << size << "," << throughput << "," << latency_us;
}
void BenchmarkDecompression(const std::string& contents,
int repeats,
bool snappy) {
std::string compressed;
if (snappy) {
snappy::Compress(contents.c_str(), contents.size(), &compressed);
} else {
CHECK(compression::GzipCompress(contents, &compressed));
}
auto tick = base::TimeTicks::Now();
for (int i = 0; i < repeats; ++i) {
std::string uncompressed;
if (snappy) {
snappy::Uncompress(compressed.c_str(), compressed.size(), &uncompressed);
} else {
CHECK(compression::GzipUncompress(compressed, &uncompressed));
}
}
auto tock = base::TimeTicks::Now();
LogThroughputAndLatency(contents.size(), repeats, tick, tock);
}
void BenchmarkCompression(const std::string& contents,
int repeats,
bool snappy) {
size_t compressed_size = 0;
auto tick = base::TimeTicks::Now();
for (int i = 0; i < repeats; ++i) {
std::string compressed;
if (snappy) {
compressed_size =
snappy::Compress(contents.c_str(), contents.size(), &compressed);
} else {
CHECK(compression::GzipCompress(contents, &compressed));
compressed_size = compressed.size();
}
}
auto tock = base::TimeTicks::Now();
double ratio = contents.size() / static_cast<double>(compressed_size);
LOG(INFO) << " Compression ratio = " << ratio;
LogThroughputAndLatency(contents.size(), repeats, tick, tock);
}
} // namespace
int main(int argc, char** argv) {
if (argc != 2) {
LOG(FATAL) << "Usage: " << argv[0] << " <filename>\n\n"
<< "Where the file contains data to compress";
return 1;
}
LOG(INFO) << "Reading the input file";
auto path = base::FilePath(std::string(argv[1]));
std::string contents;
CHECK(base::ReadFileToString(path, &contents));
constexpr size_t kPageSize = 1 << 12;
for (bool use_snappy : {false, true}) {
LOG(INFO) << "\n\n\n\n" << (use_snappy ? "Snappy" : "Gzip");
for (size_t size = kPageSize; size < contents.size() * 2; size *= 2) {
size_t actual_size = std::min(contents.size(), size);
std::string data = contents.substr(0, actual_size);
LOG(INFO) << "Size = " << actual_size;
LOG(INFO) << "Compression";
BenchmarkCompression(data, (10 * 1024 * kPageSize) / actual_size,
use_snappy); // 40MiB.
LOG(INFO) << "Decompression";
BenchmarkDecompression(data, 100, use_snappy);
}
}
return 0;
}