Wednesday, March 03, 2021

CPU Cycle Reduction

I just wanted to write a quick blurb before I run off to do other things.

Yesterday I mentioned about fixing the auto-injected navigation for the 笛子 Materials set of articles to be more mobile friendly, and also the updating of the pretty-printer to poll for changes.

I found a better way of doing the latter using MutationObserver. This reduces the amount of CPU cycles by only triggering the recursive walker when there are changes in the DOM tree. I could make it more adaptive by only running the recursive walker on the nodes that are changed, but to do it correctly will require some way of finding the set of sub-tree root nodes among the mutation list, which is annoying---it is just faster to note that there are changes made to the DOM tree, and just re-run the recursive walker.

Speaking of re-running the recursive walker, I have fixed it to be idempotent, i.e. f(f(x))=f(x), meaning that the recursive walker, when applied to the output of itself, does not change any output. This is important to avoid the leaking of unseen space characters that I use to keep certain symbols more tightly bound to each other.

The auto-injected navigation fix has the hacky styles taken out and shoved into a proper CSS file, and is working beautifully.

While doing testing on the MutationObserver, I learnt that setTimeout() uses a 32-bit signed ``integer'' for its millisecond parameter, and if there is an overflow, defaults to executing immediately. setTimeout() is used to automatically update the fuzzified update-timestamp in web pages so that the smallest viewable unit gets updated accordingly. I saw this instant execution issue when I was doing testing on a page that was last updated about 1.5 years ago---the update process was being triggered every half a second or so (instead of every 0.1 years), much to my confusion. The fix was just to clamp it down to the maximum if it is exceeded.

And with that, it is off to my next adventure.

No comments: