Magento's bin/magento executable is just a Symfony Console component. This means you can find the individual file reponsible for a single command. The naming is always the same so for setup:di:compile you can find the DiCompileCommand.php (setup/src/Magento/Setup/Console/Command/DiCompileCommand.php).
It'll always run the exeucte() method so that's where we need to look. In this function, you'll see an $operations var is set, which is filled by the getOperationsConfiguration() method. This method basically tells the DiCompileCommand what to compile.
The first thing I tried is returning just the application code generator part, like so;
private function getOperationsConfiguration( array $compiledPathsList ) { $excludePatterns = []; foreach ($this->excludedPathsList as $excludedPaths) { $excludePatterns = array_merge($excludedPaths, $excludePatterns); } return [ OperationFactory::APPLICATION_CODE_GENERATOR => [ 'paths' => [ $compiledPathsList['application'], $compiledPathsList['library'], $compiledPathsList['generated_helpers'], ], 'filePatterns' => ['php' => '/\.php$/'], 'excludePatterns' => $excludePatterns, ] ]; }
This went pretty well, compilation time was cut down dramatically;
Compilation was started. Application code generator... 1/1 [============================] 100% 45 secs 308.8 MiB Generated code and dependency injection configuration successfully.
As opposed to;
Compilation was started. Interception cache generation... 7/7 [============================] 100% 3 mins 377.0 MiBB8 MiB Generated code and dependency injection configuration successfully.
Of course, this was to be expected since we cut out a number of things. But you didn't specify which files you want to have generated. Not all files can be generated on a per-module basis, since for example, the Interception classes can be dependent on multiple modules and would therefore give you a limited output of functionality if you'd only run this for one module.
You can find the responsible generators here;
setup/src/Magento/Setup/Module/Di/App/Task/Operation/
Each class has a foreach in it, which will allow you to add an if/else with a continue to skip certain modules/paths. Maybe it would be useful to check out the Symfony Console Component Input Arguments documentation on how to feed arguments into the command.