Merge "Add unit test for cow compressor performance" into main am: f278b54731
am: b1cbaa77de
Original change: https://android-review.googlesource.com/c/platform/system/core/+/2722633 Change-Id: Ia98b81dac567ad9d5c6095fdd0fecfba00696e55 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
fef270e8e6
3 changed files with 210 additions and 1 deletions
|
@ -17,7 +17,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
#include "libsnapshot/cow_format.h"
|
||||
|
||||
namespace android {
|
||||
|
|
22
fs_mgr/libsnapshot/tools/Android.bp
Normal file
22
fs_mgr/libsnapshot/tools/Android.bp
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
cc_binary {
|
||||
name: "cow_benchmark",
|
||||
host_supported: true,
|
||||
defaults: [
|
||||
"fs_mgr_defaults",
|
||||
"libsnapshot_cow_defaults",
|
||||
],
|
||||
|
||||
srcs: ["cow_benchmark.cpp"],
|
||||
|
||||
static_libs: [
|
||||
"libsnapshot_cow",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"liblog",
|
||||
],
|
||||
|
||||
cflags: ["-Werror"],
|
||||
}
|
188
fs_mgr/libsnapshot/tools/cow_benchmark.cpp
Normal file
188
fs_mgr/libsnapshot/tools/cow_benchmark.cpp
Normal file
|
@ -0,0 +1,188 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
#include <libsnapshot/cow_compress.h>
|
||||
#include <libsnapshot/cow_format.h>
|
||||
|
||||
static const uint32_t BLOCK_SZ = 4096;
|
||||
static const uint32_t SEED_NUMBER = 10;
|
||||
|
||||
namespace android {
|
||||
namespace snapshot {
|
||||
|
||||
static std::string CompressionToString(CowCompression& compression) {
|
||||
std::string output;
|
||||
switch (compression.algorithm) {
|
||||
case kCowCompressBrotli:
|
||||
output.append("brotli");
|
||||
break;
|
||||
case kCowCompressGz:
|
||||
output.append("gz");
|
||||
break;
|
||||
case kCowCompressLz4:
|
||||
output.append("lz4");
|
||||
break;
|
||||
case kCowCompressZstd:
|
||||
output.append("zstd");
|
||||
break;
|
||||
case kCowCompressNone:
|
||||
return "No Compression";
|
||||
}
|
||||
output.append(" " + std::to_string(compression.compression_level));
|
||||
return output;
|
||||
}
|
||||
|
||||
void OneShotCompressionTest() {
|
||||
std::cout << "\n-------One Shot Compressor Perf Analysis-------\n";
|
||||
|
||||
std::vector<CowCompression> compression_list = {
|
||||
{kCowCompressLz4, 0}, {kCowCompressBrotli, 1}, {kCowCompressBrotli, 3},
|
||||
{kCowCompressBrotli, 11}, {kCowCompressZstd, 3}, {kCowCompressZstd, 6},
|
||||
{kCowCompressZstd, 9}, {kCowCompressZstd, 22}, {kCowCompressGz, 1},
|
||||
{kCowCompressGz, 3}, {kCowCompressGz, 6}, {kCowCompressGz, 9}};
|
||||
std::vector<std::unique_ptr<ICompressor>> compressors;
|
||||
for (auto i : compression_list) {
|
||||
compressors.emplace_back(ICompressor::Create(i, BLOCK_SZ));
|
||||
}
|
||||
|
||||
// Allocate a buffer of size 8 blocks.
|
||||
std::array<char, 32768> buffer;
|
||||
|
||||
// Generate a random 4k buffer of characters
|
||||
std::default_random_engine gen(SEED_NUMBER);
|
||||
std::uniform_int_distribution<int> distribution(0, 10);
|
||||
for (int i = 0; i < buffer.size(); i++) {
|
||||
buffer[i] = static_cast<char>(distribution(gen));
|
||||
}
|
||||
|
||||
std::vector<std::pair<double, std::string>> latencies;
|
||||
std::vector<std::pair<double, std::string>> ratios;
|
||||
|
||||
for (size_t i = 0; i < compressors.size(); i++) {
|
||||
const auto start = std::chrono::steady_clock::now();
|
||||
std::basic_string<uint8_t> compressed_data =
|
||||
compressors[i]->Compress(buffer.data(), buffer.size());
|
||||
const auto end = std::chrono::steady_clock::now();
|
||||
const auto latency =
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(end - start) / 1000.0;
|
||||
const double compression_ratio =
|
||||
static_cast<uint16_t>(compressed_data.size()) * 1.00 / buffer.size();
|
||||
|
||||
std::cout << "Metrics for " << CompressionToString(compression_list[i]) << ": latency -> "
|
||||
<< latency.count() << "ms "
|
||||
<< " compression ratio ->" << compression_ratio << " \n";
|
||||
|
||||
latencies.emplace_back(
|
||||
std::make_pair(latency.count(), CompressionToString(compression_list[i])));
|
||||
ratios.emplace_back(
|
||||
std::make_pair(compression_ratio, CompressionToString(compression_list[i])));
|
||||
}
|
||||
|
||||
int best_speed = 0;
|
||||
int best_ratio = 0;
|
||||
|
||||
for (size_t i = 1; i < latencies.size(); i++) {
|
||||
if (latencies[i].first < latencies[best_speed].first) {
|
||||
best_speed = i;
|
||||
}
|
||||
if (ratios[i].first < ratios[best_ratio].first) {
|
||||
best_ratio = i;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "BEST SPEED: " << latencies[best_speed].first << "ms "
|
||||
<< latencies[best_speed].second << "\n";
|
||||
std::cout << "BEST RATIO: " << ratios[best_ratio].first << " " << ratios[best_ratio].second
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
void IncrementalCompressionTest() {
|
||||
std::cout << "\n-------Incremental Compressor Perf Analysis-------\n";
|
||||
|
||||
std::vector<CowCompression> compression_list = {
|
||||
{kCowCompressLz4, 0}, {kCowCompressBrotli, 1}, {kCowCompressBrotli, 3},
|
||||
{kCowCompressBrotli, 11}, {kCowCompressZstd, 3}, {kCowCompressZstd, 6},
|
||||
{kCowCompressZstd, 9}, {kCowCompressZstd, 22}, {kCowCompressGz, 1},
|
||||
{kCowCompressGz, 3}, {kCowCompressGz, 6}, {kCowCompressGz, 9}};
|
||||
std::vector<std::unique_ptr<ICompressor>> compressors;
|
||||
for (auto i : compression_list) {
|
||||
compressors.emplace_back(ICompressor::Create(i, BLOCK_SZ));
|
||||
}
|
||||
|
||||
// Allocate a buffer of size 8 blocks.
|
||||
std::array<char, 32768> buffer;
|
||||
|
||||
// Generate a random 4k buffer of characters
|
||||
std::default_random_engine gen(SEED_NUMBER);
|
||||
std::uniform_int_distribution<int> distribution(0, 10);
|
||||
for (int i = 0; i < buffer.size(); i++) {
|
||||
buffer[i] = static_cast<char>(distribution(gen));
|
||||
}
|
||||
|
||||
std::vector<std::pair<double, std::string>> latencies;
|
||||
std::vector<std::pair<double, std::string>> ratios;
|
||||
|
||||
for (size_t i = 0; i < compressors.size(); i++) {
|
||||
std::vector<std::basic_string<uint8_t>> compressed_data_vec;
|
||||
int num_blocks = buffer.size() / BLOCK_SZ;
|
||||
const uint8_t* iter = reinterpret_cast<const uint8_t*>(buffer.data());
|
||||
|
||||
const auto start = std::chrono::steady_clock::now();
|
||||
while (num_blocks > 0) {
|
||||
std::basic_string<uint8_t> compressed_data = compressors[i]->Compress(iter, BLOCK_SZ);
|
||||
compressed_data_vec.emplace_back(compressed_data);
|
||||
num_blocks--;
|
||||
iter += BLOCK_SZ;
|
||||
}
|
||||
|
||||
const auto end = std::chrono::steady_clock::now();
|
||||
const auto latency =
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(end - start) / 1000.0;
|
||||
|
||||
size_t size = 0;
|
||||
for (auto& i : compressed_data_vec) {
|
||||
size += i.size();
|
||||
}
|
||||
const double compression_ratio = size * 1.00 / buffer.size();
|
||||
|
||||
std::cout << "Metrics for " << CompressionToString(compression_list[i]) << ": latency -> "
|
||||
<< latency.count() << "ms "
|
||||
<< " compression ratio ->" << compression_ratio << " \n";
|
||||
|
||||
latencies.emplace_back(
|
||||
std::make_pair(latency.count(), CompressionToString(compression_list[i])));
|
||||
ratios.emplace_back(
|
||||
std::make_pair(compression_ratio, CompressionToString(compression_list[i])));
|
||||
}
|
||||
|
||||
int best_speed = 0;
|
||||
int best_ratio = 0;
|
||||
|
||||
for (size_t i = 1; i < latencies.size(); i++) {
|
||||
if (latencies[i].first < latencies[best_speed].first) {
|
||||
best_speed = i;
|
||||
}
|
||||
if (ratios[i].first < ratios[best_ratio].first) {
|
||||
best_ratio = i;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "BEST SPEED: " << latencies[best_speed].first << "ms "
|
||||
<< latencies[best_speed].second << "\n";
|
||||
std::cout << "BEST RATIO: " << ratios[best_ratio].first << " " << ratios[best_ratio].second
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
} // namespace snapshot
|
||||
} // namespace android
|
||||
|
||||
int main() {
|
||||
android::snapshot::OneShotCompressionTest();
|
||||
android::snapshot::IncrementalCompressionTest();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue