From 1c88b82dfc0773b3c25b46dd5a0b01017c2ad40a Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sat, 2 Dec 2023 19:28:18 +0900 Subject: [PATCH] LibPDF: Do less work in SampledFunction::evaluate()'s inner loop Instead of recomputing the left index and the float amount in that interval for each coordinate all the time, do it once when we preprocess the input coordinates. One line less, faster, and arguably easier to read. No behavior change. --- Userland/Libraries/LibPDF/Function.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Userland/Libraries/LibPDF/Function.cpp b/Userland/Libraries/LibPDF/Function.cpp index 561d2799fe..679e2b76ff 100644 --- a/Userland/Libraries/LibPDF/Function.cpp +++ b/Userland/Libraries/LibPDF/Function.cpp @@ -68,6 +68,7 @@ private: ReadonlyBytes m_sample_data; Vector mutable m_inputs; + Vector mutable m_left_index; Vector mutable m_outputs; }; @@ -167,6 +168,7 @@ SampledFunction::create(Document* document, Vector domain, Optionalm_encode = move(encode); function->m_decode = move(decode); function->m_inputs.resize(function->m_domain.size()); + function->m_left_index.resize(function->m_domain.size()); function->m_outputs.resize(function->m_range.size()); return function; } @@ -189,8 +191,11 @@ PDFErrorOr> SampledFunction::evaluate(ReadonlySpan xs for (size_t i = 0; i < m_domain.size(); ++i) { float x = clamp(xs[i], m_domain[i].lower, m_domain[i].upper); float e = interpolate(x, m_domain[i].lower, m_domain[i].upper, m_encode[i].lower, m_encode[i].upper); - float ec = clamp(e, 0.0f, static_cast(m_sizes[i] - 1)); - m_inputs[i] = ec; + + unsigned n = m_sizes[i] - 1; + float ec = clamp(e, 0.0f, static_cast(n)); + m_left_index[i] = min(ec, n - 1); + m_inputs[i] = ec - m_left_index[i]; } for (size_t r = 0; r < m_range.size(); ++r) { @@ -207,20 +212,14 @@ PDFErrorOr> SampledFunction::evaluate(ReadonlySpan xs Vector coordinates; coordinates.resize(m_domain.size()); for (size_t mask = 0; mask < (1u << m_domain.size()); ++mask) { - for (size_t i = 0; i < m_domain.size(); ++i) { - unsigned n = m_sizes[i] - 1; - unsigned left_index = min(m_inputs[i], n - 1); - coordinates[i] = left_index + ((mask >> i) & 1u); - } + for (size_t i = 0; i < m_domain.size(); ++i) + coordinates[i] = m_left_index[i] + ((mask >> i) & 1u); samples[mask] = sample(coordinates, r); } for (int i = static_cast(m_domain.size() - 1); i >= 0; --i) { - unsigned n = m_sizes[i] - 1; - float ec = m_inputs[i]; - unsigned e0 = min(static_cast(ec), n - 1); for (size_t mask = 0; mask < (1u << i); ++mask) - samples[mask] = mix(samples[mask], samples[mask | (1 << i)], ec - e0); + samples[mask] = mix(samples[mask], samples[mask | (1 << i)], m_inputs[i]); } float result = interpolate(samples[0], 0.0f, 255.0f, m_decode[r].lower, m_decode[r].upper);