Skip to content

Instantly share code, notes, and snippets.

@Araq
Created November 21, 2012 19:10
Show Gist options
  • Save Araq/4126968 to your computer and use it in GitHub Desktop.
Save Araq/4126968 to your computer and use it in GitHub Desktop.
Optimizing dynamic dispatch
if a of Z:
echo "Z"
elif a of Y:
echo "Y"
elif a of X:
echo "X"
'of' is expensive and will become MORE expensive for proper DLL support
(string comparisons!). Thus we reserve a slot for the exact matched object
type and short-cut the code:
if getClass(a) == slot:
goto jmpTarget
if a of Z:
jmpTarget = thisBranch
echo "Z"
elif a of Y:
jmpTarget = thisBranch
echo "Y"
elif a of X:
jmpTarget = thisBranch
echo "X"
slot = getClass(a) # not valid because of exceptions
--> move to 'jmpTarget=' :-(
--> without computed gotos:
if getClass(a) == slot:
case jmpTarget
of 0: L0:
echo "Z"
of 1: L1:
echo "Y"
of 2: L2:
echo "X"
return
slot = getClass(a)
if a of Z:
jmpTarget = 0
goto L0
elif a of Y:
jmpTarget = 1
goto L1
elif a of X:
jmpTarget = 2
goto L2
Note: It is NOT possible to make 'slot' part of the object type descriptor!
'slot' depends on the concrete dispatcher and there can be more than 1 method
for an object type. ;-)
However we can do:
FastDispatch:
case jmpTarget
of 0:
if getClass(a) == slot:
L0:
echo "Z"
else:
goto SlowDispatch
of 1: L1:
echo "Y"
of 2: L2:
echo "X"
return
SlowDispatch:
slot = getClass(a)
if a of Z:
jmpTarget = 0
goto L0
elif a of Y:
jmpTarget = 1
goto L1
elif a of X:
jmpTarget = 2
goto L2
--> First version is simpler and produces smaller code.
--> Generalization to a multi method:
if getClass(a) == slotA and getClass(b) == slotB:
case jmpTarget
of 0: L0:
echo "Z"
of 1: L1:
echo "Y"
of 2: L2:
echo "X"
return
slotA = getClass(a)
slotB = getClass(b)
if a of Z and b of Z:
jmpTarget = 0
goto L0
elif a of Y and b of X:
jmpTarget = 1
goto L1
elif a of X and b of Y:
jmpTarget = 2
goto L2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment