I’m investigating a spike in app compilation times, and would appreciate ideas / validation of the paths I am exploring.
I have a huge app at hand, consisting of hundreds of .ex
files. Recently, our team noticed that changes to even seemingly innocent / un-related files cause a massive recompilation of more than 120 files in the project.
Using git-bisect & a small homegrown script that “measures” recompilation, I’ve boiled down an issue to a particular commit from a couple of months back. The script, in a nutshell, does this (original script omitted for brevity):
mix compile # takes time
mix compile # instant
echo "# just a comment" >> lib/my_module.ex
mix compile # takes time
With the problematic commit checked out, the last line of the script above causes more than 120 files to re-compile. With an immediate parent commit checked out, the script causes recompilations of only slightly over 30 files.
Carefully inspecting the diff of the offending commit, and playing with modifications to its patch, I’ve boiled it down to a particular line that refers to lib/my_other_module.ex
module. If the line (e.g. a reference to the module) is removed, recompilations are back to normal ~30. But there’s problem:
- the modified patch in question has no apparent relation to
lib/my_module.ex
, - the modified line with reference to
lib/my_other_module.ex
also has no apparent visible relation tolib/my_module.ex
.
I am now trying to find an answer to a question: what is it in the relationship between lib/my_module.ex
and lib/my_other_module.ex
that causes recompilation? With this question in mind, I started running experiments using mix xref
.
One particular test revealed a dramatic increase in compile-time dependencies for lib/my_module.ex
:
$ git checkout 495b41fa
$ mix xref graph --label compile --sink lib/my_module.ex --only-nodes | wc -l
0
$ git checkout 1204cb24
$ mix xref graph --label compile --sink lib/my_module.ex --only-nodes | wc -l
122
This change in number is… intriguing. But frankly, I am not sure where to go from here
I’ll continue my investigation, but in the meantime: is there any other data I should look at when running mix xref graph
that could bring me closer to understanding what’s going on?