From e5ac04496952e2773d83e26d7e1e032dd830a225 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 22 Jul 2017 18:43:03 -0700 Subject: [PATCH] [varLib] Speed up IUP DP some more when forced set is empty Pass a maximum lookback of n to the circle-breaking DP of size 2*n. This should theoretically speed up that DP by a factor of 4 or 8 or something... Empirically it's far from that, but solidly measurable. Again, gvar table size got a slight improvement, which I didn't expect... It might be that my one test is hitting lucky cases with point encodings.. or it might be just me wishfully thinking so. --- Lib/fontTools/varLib/__init__.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/fontTools/varLib/__init__.py b/Lib/fontTools/varLib/__init__.py index aba0f5da5..0551c88aa 100644 --- a/Lib/fontTools/varLib/__init__.py +++ b/Lib/fontTools/varLib/__init__.py @@ -246,7 +246,7 @@ def _iup_contour_bound_forced_set(delta, coords, tolerance=0): return forced -def _iup_contour_optimize_dp(delta, coords, forced={}, tolerance=0): +def _iup_contour_optimize_dp(delta, coords, forced={}, tolerance=0, lookback=None): """Straightforward Dynamic-Programming. For each index i, find least-costly encoding of points i to n-1 where i is explicitly encoded. We find this by considering all next explicit points j and check whether interpolation can fill points between i and j. @@ -257,6 +257,8 @@ def _iup_contour_optimize_dp(delta, coords, forced={}, tolerance=0): As major speedup, we stop looking further whenever we see a "forced" point.""" n = len(delta) + if lookback is None: + lookback = n costs = {-1:0} chain = {-1:None} for i in range(0, n): @@ -268,7 +270,7 @@ def _iup_contour_optimize_dp(delta, coords, forced={}, tolerance=0): if i - 1 in forced: continue - for j in range(i-2, -2, -1): + for j in range(i-2, max(i-lookback, -2), -1): cost = costs[j] + 1 @@ -343,8 +345,7 @@ def _iup_contour_optimize(delta, coords, tolerance=0.): delta = _rot_list(delta, -k) else: - chain, costs = _iup_contour_optimize_dp(delta+delta, coords+coords, forced, tolerance) - # TODO add lookback=n to DP + chain, costs = _iup_contour_optimize_dp(delta+delta, coords+coords, forced, tolerance, n) best_sol, best_cost = None, n+1 for start in range(n-1, 2*n-1):