[cffLib.specializer] Make command-merging linear again
The consideration for blends had made it into O(n^2). Make it linear again. Speeds up Tests/cffLib/specializer_test.py::CFFSpecializeProgramTest::test_maxstack_blends 3x for me.
This commit is contained in:
parent
7e6d31569f
commit
cfba1f995f
@ -715,6 +715,7 @@ def specializeCommands(
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# 5. Combine adjacent operators when possible, minding not to go over max stack size.
|
# 5. Combine adjacent operators when possible, minding not to go over max stack size.
|
||||||
|
stackUse = _argsStackUse(commands[-1][1]) if commands else 0
|
||||||
for i in range(len(commands) - 1, 0, -1):
|
for i in range(len(commands) - 1, 0, -1):
|
||||||
op1, args1 = commands[i - 1]
|
op1, args1 = commands[i - 1]
|
||||||
op2, args2 = commands[i]
|
op2, args2 = commands[i]
|
||||||
@ -764,19 +765,14 @@ def specializeCommands(
|
|||||||
|
|
||||||
# Make sure the stack depth does not exceed (maxstack - 1), so
|
# Make sure the stack depth does not exceed (maxstack - 1), so
|
||||||
# that subroutinizer can insert subroutine calls at any point.
|
# that subroutinizer can insert subroutine calls at any point.
|
||||||
#
|
args1StackUse = _argsStackUse(args1)
|
||||||
# The assumption is that args1, and args2, each individually
|
combinedStackUse = max(args1StackUse, len(args1) + stackUse)
|
||||||
# can be successfully processed without a stack overflow.
|
if new_op and combinedStackUse < maxstack:
|
||||||
# When combined, the stack depth to consider would be the
|
|
||||||
# number of items in args1 plus what it takes to build args2
|
|
||||||
# on top of args1, which will be already on the stack as
|
|
||||||
# len(args1) items.
|
|
||||||
#
|
|
||||||
# It's unfortunate that _argsStackUse() is O(n) in the number
|
|
||||||
# of args, but it's not a big deal hopefully.
|
|
||||||
if new_op and len(args1) + _argsStackUse(args2) < maxstack:
|
|
||||||
commands[i - 1] = (new_op, args1 + args2)
|
commands[i - 1] = (new_op, args1 + args2)
|
||||||
del commands[i]
|
del commands[i]
|
||||||
|
stackUse = combinedStackUse
|
||||||
|
else:
|
||||||
|
stackUse = args1StackUse
|
||||||
|
|
||||||
# 6. Resolve any remaining made-up operators into real operators.
|
# 6. Resolve any remaining made-up operators into real operators.
|
||||||
for i in range(len(commands)):
|
for i in range(len(commands)):
|
||||||
|
@ -599,8 +599,8 @@ class CFFSpecializeProgramTest:
|
|||||||
stack_use = charstr_stack_use(specialized, getNumRegions=getNumRegions)
|
stack_use = charstr_stack_use(specialized, getNumRegions=getNumRegions)
|
||||||
assert maxStack - numRegions < stack_use < maxStack
|
assert maxStack - numRegions < stack_use < maxStack
|
||||||
|
|
||||||
def test_maxstack_blends2(self):
|
def test_maxstack_commands(self):
|
||||||
# See if two long blend sequences are merged into one
|
# See if two commands with deep blends are merged into one
|
||||||
numRegions = 400
|
numRegions = 400
|
||||||
numOps = 2
|
numOps = 2
|
||||||
getNumRegions = lambda iv: numRegions
|
getNumRegions = lambda iv: numRegions
|
||||||
|
Loading…
x
Reference in New Issue
Block a user