Emacs has experienced a significant performance boost with the introduction of native compilation, available from version 27 and above. This feature converts Emacs Lisp code into machine-level code, enabling faster execution and enhanced responsiveness.
Speeding up compilation by using the maximum number of available CPU cores significantly reduces compilation time. However, it’s also necessary to leave a few CPU cores free to ensure the operating system runs smoothly, including the graphical user interface, shells, and other processes. The source code snippet outlined in this article is designed to effectively manage resources by allocating CPU cores for native compilation while reserving some for system operations.
Configuring native compilation and adjusting the number of parallel compilations
To configure native compilation and dynamically adjust the number of parallel compilations, add the following code snippet to early-init.el
or init.el
:
;; Description: Enable native compilation and dynamically adjust
;; the number of Elisp files compiled in parallel.
;;
;; Compatible with: Emacs >= 28.1 (because `num-processors' is required)
;;
;; URL: https://www.jamescherti.com/emacs-native-compilation-config-jobs/
;; License: MIT
;; Author: James Cherti
(defvar my-native-comp-reserved-cpus 2
"Number of CPUs to reserve and not use for `native-compile'.")
(defun my-calculate-native-comp-async-jobs ()
"Set `native-comp-async-jobs-number' based on the available CPUs."
;; The `num-processors' function is only available in Emacs >= 28.1
(max 1 (- (num-processors) my-native-comp-reserved-cpus)))
(if (and (featurep 'native-compile)
(fboundp 'native-comp-available-p)
(native-comp-available-p))
;; Activate `native-compile'
(setq native-comp-async-jobs-number (my-calculate-native-comp-async-jobs)
native-comp-deferred-compilation t
package-native-compile t)
;; Deactivate the `native-compile' feature if it is not available
(setq features (delq 'native-compile features)))
Code language: Lisp (lisp)
What does the source code snippet above do?
- Reserves CPUs: Sets aside 2 CPUs to not be used by the native compilation feature in Emacs.
- Calculates Available CPUs for Compilation: Determines how many CPUs can be used for compiling Emacs Lisp files by subtracting the reserved CPUs from the total count.
- Sets Native Compilation Parameters: Configures Emacs to use the calculated number of CPUs for parallel compilation tasks.
- Ensures Feature Availability: Activates native compilation settings only if the feature is supported and available, otherwise deactivates it.
- Optimizes Performance: Aims to enhance Emacs performance by efficiently using system resources without overloading the system.
How to check if native compilation is available?
To check whether native compilation is supported, you can run the following Emacs Lisp code:
(message (if (and (fboundp 'native-comp-available-p)
(native-comp-available-p))
"Native compilation is available"
"Native compilation is *not* available"))
Code language: Lisp (lisp)
Conclusion
Managing system resources efficiently is key to maintaining optimal performance in Emacs, especially when using the native compilation feature. The source code snippet outlined in this article provides a dynamic method for adjusting the number of native compilation jobs according to the number of available CPUs. This enhances the responsiveness and efficiency of Emacs without overloading the system.