diff --git a/Tests/LibPDF/BenchmarkPDF.cpp b/Tests/LibPDF/BenchmarkPDF.cpp new file mode 100644 index 0000000000..35155098a2 --- /dev/null +++ b/Tests/LibPDF/BenchmarkPDF.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024, Nico Weber + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +static PDF::Value make_array(Vector floats) +{ + Vector values; + for (auto f : floats) + values.append(PDF::Value { f }); + return PDF::Value { make_object(move(values)) }; +} + +static PDF::PDFErrorOr> make_function(int type, ReadonlyBytes data, Vector domain, Vector range, Function&)> extra_keys = nullptr) +{ + HashMap map; + map.set(PDF::CommonNames::FunctionType, PDF::Value { type }); + map.set(PDF::CommonNames::Domain, make_array(move(domain))); + map.set(PDF::CommonNames::Range, make_array(move(range))); + if (extra_keys) + extra_keys(map); + auto dict = make_object(move(map)); + auto stream = make_object(dict, MUST(ByteBuffer::copy(data))); + + // document isn't used for anything, but UBSan complains about a (harmless) method call on a null object without it. + auto file = MUST(Core::MappedFile::map("linearized.pdf"sv)); + auto document = MUST(PDF::Document::create(file->bytes())); + return PDF::Function::create(document, stream); +} + +static PDF::PDFErrorOr> make_sampled_function(ReadonlyBytes data, Vector domain, Vector range, Vector sizes) +{ + return make_function(0, data, move(domain), move(range), [&sizes](auto& map) { + map.set(PDF::CommonNames::Size, make_array(sizes)); + map.set(PDF::CommonNames::BitsPerSample, PDF::Value { 8 }); + }); +} + +static PDF::PDFErrorOr> make_bench_sampled_function() +{ + Vector domain = { 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f }; + Vector range = { 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f }; + Vector sizes = { 9, 9, 9, 9 }; + Vector data; + size_t total_size = range.size() / 2; + for (auto size : sizes) + total_size *= static_cast(size); + data.resize(total_size); + return make_sampled_function(data.span(), move(domain), move(range), move(sizes)); +} + +BENCHMARK_CASE(function) +{ + auto bench_function = MUST(make_bench_sampled_function()); + + Vector inputs; + inputs.resize(4); + for (int i = 0; i < 500'000; ++i) { + inputs[0] = i * 31; + inputs[1] = i * 19; + inputs[2] = i * 103; + inputs[3] = i * 7; + auto result = MUST(bench_function->evaluate(inputs)); + VERIFY(result[0] == 0); + VERIFY(result[1] == 0); + VERIFY(result[2] == 0); + } +} diff --git a/Tests/LibPDF/CMakeLists.txt b/Tests/LibPDF/CMakeLists.txt index 8ed4779bc4..fe57676933 100644 --- a/Tests/LibPDF/CMakeLists.txt +++ b/Tests/LibPDF/CMakeLists.txt @@ -1,4 +1,5 @@ set(TEST_SOURCES + BenchmarkPDF.cpp TestPDF.cpp )