Welcome to the next chapter of my CI/CD series, where we discuss possible approaches toward software development with InterSystems technologies and GitLab.
Today I want to share a few approaches that will decrease your compilation time (especially if you're doing incremental/diff compilation rather than a full build).
Compiler flags and qualifiers
Code load and compilation are affected by a variety of flags and qualifiers. If you write deployment scripts for InterSystems platforms, I highly recommend reading them at least once through. While most have very specific uses, knowing what is possible can save you a lot of time one day. To list all of them, call:
Do $system.OBJ.ShowFlags()
Do $system.OBJ.ShowQualifiers()
They are also described in the docs. In any case, the most important flag here is u (update only) - if present, it skips compilation of classes that are already up-to-date. In the case where you're doing incremental compilation, having this flag saves 99% of time since only the modified code would be compiled.
Load only the modified code
Recursive Import is good, but if you have a thousand classes and changed only two of them in the last commit, that's 998 classes to load for no reason at all (besides simplicity). Thankfully, git can easily answer questions, such as "what files were changed between commits abc and xyz?" Here's a sample code that accepts two git identifiers (commits, branch names, tags) and returns three lists:
- Added files
- Modified files
- Deleted files
Added and modified files can be simply loaded; however, for deleted files, you'll need to write an extra handler that can determine the class name from the filename. So, in effect, you need to implement the following flow:
- Get the last commit hash deployed into the environment.
- Get the commit has to deploy.
- Build a diff between commits.
- Load and compile all added/modified classes.
- Delete classes based on deleted files.
- Store the latest commit hash (2) in IRIS.
Which is a bit more complicated to implement and maintain than just Import, but you'll considerably decrease load times.
Minimize passes
Ideally you'll call Import and Compile once, each (or just import with compile flags). The worst flow (from the time perspective) is to load and compile each class one by one. While in some cases multi-stage load/compile is unavoidable, try to minimize the number of passes, especially compilation passes.
Import method returns a local with all loaded items, so if you have several unrelated directories and you compile like this:
- Load and compile dir A
- Load and compile dir B
- Load and compile dir C
You can speed things up by doing it like this instead:
- Load dir A and get a list of loaded items
- Load dir B and get a list of loaded items
- Load dir C and get a list of loaded items
- Combine lists A, B, and C
- Compile combined list A, B, and C
Conclusion
In some cases it's possible to decrease compilation times a lot. Are there any tricks and trips you're using? Please share them in the comments.
.jpg)
.png)