The third round of performance work went after the cost every script pays on every bar
The first two rounds were about request.security. Multi-timeframe scripts were paying far more than they should, and they got several times faster. This one is about the per-bar cost a script pays whether or not it ever reads another timeframe.
Most of the work happens before a script runs. Simple built-in calls get rewritten into the expression they compute, so a square root or an array lookup no longer costs a function call. Typing scaffolding is stripped out of the code at load time, including from PyneCore’s own hot paths. Number formatting, which plenty of scripts do on every bar, no longer detours through arbitrary-precision arithmetic. Library calls that keep no state are recognised as such and stop paying for bookkeeping they never use, which costs the most inside loops. strategy.exit leaves a resting order alone when the call would only rebuild it unchanged.
The six heaviest single-timeframe scripts in the public corpus were run on the previous release and on this one over identical data. They came out between barely changed and twice as fast, the heaviest dropping from 133 seconds to 69, and every output was byte-identical across the two runs. How much a script gains depends on how much of its time sat in call overhead and number formatting, which varies with the author’s style.
One change is Linux-only and invisible on a Mac, where committing to disk costs almost nothing. Building or downloading a data feed used to force a commit twice for every bar. It now commits once per batch, while a live bar still commits on its own. Fetching a feed for a three-timeframe script went from just under a minute of waiting on the disk to under two seconds.