Y a-t-il un inconvénient à définir `gc-cons-threshold` très haut et à collecter les ordures lorsqu'il est inactif?

17

J'ai ajouté les deux lignes suivantes en haut de mon init.el:

(setq gc-cons-threshold (eval-when-compile (* 1024 1024 1024)))
(run-with-idle-timer 2 t (lambda () (garbage-collect)))

Cela signifie qu'au lieu de collecter les ordures tous les 800 Ko de mémoire allouée, Emacs le fait lorsqu'il est inactif, c'est-à-dire lorsque la pause ne me dérange pas. (Il collecte également après l'allocation de 1 Go de mémoire, mais je ne pense pas que cela se produira).

Cela a amélioré mon temps de démarrage d'environ deux tiers. En théorie, cela devrait également améliorer les performances en général. Y a-t-il des inconvénients à cette approche?

Erik
la source
1
En principe , vous ne devez pas définir gc-cons-thresholdplus haut que vous êtes prêt à frapper effectivement à un moment donné, parce que vous devez supposer que vous allez réellement atteindre cette valeur de temps en temps (après tout, qui sait peut - être accumulé d' ordures par une tâche non inactive enthousiaste inattendue). Je ne vois pas de problème particulier avec le déclenchement de gc avec une minuterie inactive, mais je pense que fixer le seuil pour gc non-inactif aussi haut que cela semble OTT, et mon impression est que la valeur a probablement été choisie comme étant "plus élevée que je aurai jamais besoin de "plutôt que" du plus haut que je suis prêt à utiliser ".
phils
5
Selon ce post de Stefan Monnier : "Mieux vaut ne pas y toucher. Dans Emacs-22, nous avons introduit gc-contre-pourcentage qui offre le même avantage que l'augmentation du seuil de gc contre, mais sans les inconvénients. Et sans avoir à jouer avec. C'est-à-dire que je recommanderais aux utilisateurs de supprimer tous les paramètres gc-cons-threshold de leurs .emacs. "
izkon
1
@izkon, sauf que le message auquel vous avez lié remonte à 2007, tandis que, par exemple, ce message , où quelqu'un a réellement expérimenté - et la modification du seuil a fait la différence - remonte à 2016. Donc, soit il a régressé, soit la solution de contournement n'a jamais été a bien fonctionné.
Hi-Angel
1
@Erik Je pense que vous pouvez remplacer (eval-when-compile (* 1024 1024 1024))par most-positive-fixnum (veuillez le faire, je suis sûr que tous ceux qui rencontrent votre question copient votre code dans leur configuration) .
Hi-Angel
2
@ Hi-Angel, je ne pense pas que ce soit une bonne idée. Si Emacs alloue réellement d'énormes quantités de mémoire sans devenir inactif, il devrait gc au lieu de continuer à allouer jusqu'à ce que le système doive échanger ou même manquer de mémoire. Si quoi que ce soit, 1 Go est déjà trop élevé.
Erik

Réponses:

4

Pour autant que je sache, si vous avez la RAM, ça va, mais si Emacs a déjà atteint un niveau d'utilisation très élevé avant le GC, cela pourrait prendre beaucoup de temps. Je ne sais pas exactement ce que veut dire Eli; ISTM que si vous avez assez de mémoire, ça devrait aller, mais c'est l'expert ici.

Cela dit, j'utilise ces lignes dans mon fichier init depuis un certain temps maintenant, et cela aide à réduire le temps de démarrage sans rendre les modifications permanentes:

;;;;; Startup optimizations

;;;;;; Set garbage collection threshold

;; From https://www.reddit.com/r/emacs/comments/3kqt6e/2_easy_little_known_steps_to_speed_up_emacs_start/

(setq gc-cons-threshold-original gc-cons-threshold)
(setq gc-cons-threshold (* 1024 1024 100))

;;;;;; Set file-name-handler-alist

;; Also from https://www.reddit.com/r/emacs/comments/3kqt6e/2_easy_little_known_steps_to_speed_up_emacs_start/

(setq file-name-handler-alist-original file-name-handler-alist)
(setq file-name-handler-alist nil)

;;;;;; Set deferred timer to reset them

(run-with-idle-timer
 5 nil
 (lambda ()
   (setq gc-cons-threshold gc-cons-threshold-original)
   (setq file-name-handler-alist file-name-handler-alist-original)
   (makunbound 'gc-cons-threshold-original)
   (makunbound 'file-name-handler-alist-original)
   (message "gc-cons-threshold and file-name-handler-alist restored")))
blujay
la source
Pourquoi n'utilisez-vous pas after-init-hook?
Erik
3
Parce que cela s'exécuterait immédiatement après l'initialisation, ce qui pourrait faire attendre l'utilisateur pour GC. En utilisant une minuterie inactive, il peut s'exécuter lorsque l'utilisateur n'utilise pas Emacs.
blujay