Model checks on large models can take several minutes. Profiling one of such long-running checks, I found that it spent minutes checking reference scopes. The model I was checking had about 130 thousand references and a scope had to be computed and checked for each one. Very often these scopes would turn out to be identical, but there was no way to avoid recomputing them over and over.

The MPS team must have encountered of these problems as well, since the MPS 2021.2 introduced an enhancement to the constraints language to cache scopes.

Unfortunately, I couldn’t use the new feature. First, my project is still using MPS 2020.3 and upgrading to 2021.2 looks to be a matter of distant future. Second, I wanted to choose my own cache keys but the new language concepts only support caching some predefined scope pieces. Third, the scope cache in MPS 2021.2 is only accessible from the constraints language, but half of the references in my large model used inherited scopes (the ScopeProvider mechanism) and the code computing the scopes would live in the behavior model where the new language could not be used.

However, I liked the underlying idea and runtime. It was fairly straightforward to reimplement a similar runtime for MPS 2020.3. I didn’t bother with any language extensions yet but I could make it work with ScopeProviders.

After using the scope cache in my project the time of scope checks was reduced from several minutes to several seconds.

I have published the scope cache as a library on GitHub with documentation in the README file and pre-built packages available from GitHub Packages and JitPack.