浏览代码

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.
Nico Weber 1 年之前
父节点
当前提交
1c88b82dfc
共有 1 个文件被更改,包括 10 次插入11 次删除
  1. 10 11
      Userland/Libraries/LibPDF/Function.cpp

+ 10 - 11
Userland/Libraries/LibPDF/Function.cpp

@@ -68,6 +68,7 @@ private:
     ReadonlyBytes m_sample_data;
 
     Vector<float> mutable m_inputs;
+    Vector<unsigned> mutable m_left_index;
     Vector<float> mutable m_outputs;
 };
 
@@ -167,6 +168,7 @@ SampledFunction::create(Document* document, Vector<Bound> domain, Optional<Vecto
     function->m_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<ReadonlySpan<float>> SampledFunction::evaluate(ReadonlySpan<float> 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<float>(m_sizes[i] - 1));
-        m_inputs[i] = ec;
+
+        unsigned n = m_sizes[i] - 1;
+        float ec = clamp(e, 0.0f, static_cast<float>(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<ReadonlySpan<float>> SampledFunction::evaluate(ReadonlySpan<float> xs
         Vector<int> 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<int>(m_domain.size() - 1); i >= 0; --i) {
-            unsigned n = m_sizes[i] - 1;
-            float ec = m_inputs[i];
-            unsigned e0 = min(static_cast<unsigned>(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);