I added the following two lines to the top of my init.el:

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

That means that instead of collecting garbage every 800kb of allocated memory, Emacs does so when idle, i.e. when the pausing does not bother me. (It also collects after allocating 1GB of memory, but I don't think that will happen).

This improved my startup time by about two thirds. In theory, it should also improve performance in general. Are there any downsides to this approach?

share|improve this question
    
FWIW, I haven't touched the garbage collection settings, and have never been aware of it during normal operations. – Dan Jul 22 at 14:10
    
I re-posted a link to this thread over on reddit/emacs reddit.com/r/emacs/comments/6ow208/… and Eli Z. (a lead developer/maintainer of Emacs) has already posted a comment. There may be additional comments within the next few days. – lawlist Jul 22 at 17:25
1  
In principle you shouldn't set gc-cons-threshold any higher than you're willing to actually hit at any given time, because you ought to assume that you will actually hit that value from time to time (after all, who knows how much garbage might be accrued by some unexpectedly-enthusiastic non-idle task). I don't see a particular problem with triggering gc with an idle timer, but I think setting the threshold for non-idle gc as high as this seems OTT, and my impression is that the value was probably chosen as being "higher than I'll ever need" rather than "the highest I'm willing to use". – phils Jul 24 at 1:28
    
In any case, assuming you actually have enough RAM to support the chosen value, the obvious downside to doing this is that Emacs may be unresponsive for longer than desirable during gc; but I don't have any numbers (and they would be system-dependent in any case), so I guess you should do some testing and report back? – phils Jul 24 at 1:39
    
@phils: I'm aware that GC makes Emacs unresponsive and collecting only every 1GB would lead to noticable pauses. As I understand it, gc-cons-threshold is set so low in part to keep each pause shorter. If the pause occurs during idle time, I don't notice it either. – Erik Jul 24 at 22:23

As far as I know, if you have the RAM, it's okay, but if Emacs ever did hit really high usage before GC'ing, it might take a long time. I'm not sure exactly what Eli means; ISTM that if you have enough memory, it should be okay, but he's the expert here.

Having said that, I've used these lines in my init file for a while now, and it helps reduce startup time without making the changes permanent:

;;;;; 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")))
share|improve this answer
    
Why don't you use after-init-hook? – Erik Jul 24 at 23:06
1  
Because that would run immediately after initialization, which might make the user wait for GC. By using an idle timer, it can run when the user's not using Emacs. – blujay Jul 26 at 8:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.