Closed ChrisPenner closed 2 months ago
Looking pretty good so far! Though less dramatic than I hoped. I'll be curious to see it with the same treatment applied to foreign function calls (not sure if you're planning separate PR for that), I'm guessing that will make the JSON decoding and other benchmarks that use a lot of foreign calls go faster.
Note that trunk is going to be worse the more code you have loaded, since the IntMap
will have greater depth. A best case scenario for trunk is running benchmarks after freshly starting up UCM (or you can use compile
command with ucm run.compiled
).
But this isn't terribly realistic since (for instance) Unison Cloud nodes are kept running and are loading new code all the time. And most users aren't bouncing UCM willy nilly.
Reading through some of this, something occurred to me. Is there even a reason for us to number the term references at this point?
I guess it's a little more economical to make numbers for the references and store the latter once for e.g. compiled data. But for actual code functionality, we just make up numbers for the references, then get rid of the numbers by making things circular, right?
And yes, I'll do the Foreign Funcs as a separate PR so we can track each performance change individually.
@dolio
Is there even a reason for us to number the term references at this point? I guess it's a little more economical to make numbers for the references and store the latter once for e.g. compiled data. But for actual code functionality, we just make up numbers for the references, then get rid of the numbers by making things circular, right?
Yeah I think you're right, though tbh it's probably more work to remove them than it's worth at this point, I don't think they're doing any harm 🤷🏼♂️
Yeah, I wouldn't try to remove the numbering I guess.
Actually, the CI failures look suspicious. The mac one reports a stack overflow on the codeops
test, so something there might be doing something bad with a circular representation.
There's an infinite loop when testing equality on recursive functions; I'm guessing we're naively crawling through and checking equality on all contained sections; probably just need to lower back to combix's when checking equality. Don't worry, we won't merge until CI is passing 😄
Failure case:
testcase = do
f n = if n == 0 then 0 else f (Nat.drop 1 n)
f == f
Oh, right.
Actually, you should just not derive Eq
and Ord
for RComb
. It should test equality via the stored CombIx
, no?
For that matter, I guess the Show
instance for RComb
could be more informative using the CombIx
, too, right?
Haha, yeah I had the exact same ideas 😄
We've passed the nimbus test-suite now as well ✅
Overview
Previously we stored only references to the code we wanted to jump to in things like function calls/applications even though the code each reference referred to was known at the time we translate to MCode.
This change statically resolves each reference to the code it refers to at code generation time, avoiding lookups at runtime.
Implementation notes
comb
type such that we can build the computations usingCombIx
, then "tie the knot" and resolve toCombs
using a fixed point.-O1
by Dan's suggestion, O2 is pretty intense (and slow) and can probably be sequestered off to just the runtime package now that it's split off to improve build times.~ Reverted by Paul's requestInteresting/controversial decisions
Test coverage
Benchmarks:
@pchiusano/misc-benchmarks/chris:.suite
@mitchellwrosen/mbta/@mitchellwrosen/branch-for-chris:.runTheBenchmark
Loose ends
Nope.