Existe alguma desvantagem em definir o `gc-cons-threshold 'muito alto e coletar lixo quando ocioso?

17

Adicionei as duas linhas a seguir na parte superior da minha init.el:

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

Isso significa que, em vez de coletar lixo a cada 800kb de memória alocada, o Emacs o faz quando ocioso, ou seja, quando a pausa não me incomoda. (Ele também é coletado após a alocação de 1 GB de memória, mas não acho que isso aconteça).

Isso melhorou meu tempo de inicialização em cerca de dois terços. Em teoria, também deve melhorar o desempenho em geral. Há alguma desvantagem nessa abordagem?

Erik
fonte
1
Em princípio, você não deve definir gc-cons-thresholdqualquer maior do que você está disposto a realmente acertar a qualquer momento, porque você deve assumir que você vai realmente bater esse valor ao longo do tempo (afinal, quem sabe o quanto de lixo pode ser acumulado por uma tarefa não ociosa inesperadamente entusiasmada). Não vejo um problema específico ao acionar o gc com um timer ocioso, mas acho que definir o limite para o gc não ocioso tão alto quanto parece OTT, e minha impressão é que o valor provavelmente foi escolhido como "mais alto do que eu" sempre precisará "em vez de" o mais alto que estou disposto a usar ".
phils
5
De acordo com este post de Stefan Monnier : "É melhor não tocá-lo. No Emacs-22, introduzimos o gc-cons-percentual, que oferece o mesmo benefício que o aumento do limite de gc-cons-mas sem os inconvenientes. E sem ter que mexer com isso. Ou seja, eu recomendo que os usuários removem qualquer configuração de gc-cons-threshold de seus .emacs. "
izkon
1
@izkon, exceto que a postagem que você vinculou remonta a 2007, enquanto, por exemplo, esta postagem , onde alguém realmente experimentou - e alterar o limite fez a diferença - remonta a 2016. Portanto, ele regrediu ou a solução alternativa nunca funcionou bem.
Hi-Angel
1
@ Erik Eu acho que você pode substituir (eval-when-compile (* 1024 1024 1024))por most-positive-fixnum (por favor, faça isso, tenho certeza que todo mundo que se deparar com sua pergunta copia seu código em sua configuração) .
Hi-Angel
2
@ Oi, Angel, não acho que seja uma boa ideia. Se o Emacs realmente alocar grandes quantidades de memória sem ficar ocioso, ele deve gc em vez de continuar alocando até que o sistema precise trocar ou até ficar completamente sem memória. Se alguma coisa, 1 GB já é muito alto.
Erik

Respostas:

4

Até onde eu sei, se você tem RAM, está tudo bem, mas se o Emacs tiver atingido um uso realmente alto antes da gravação em GC, poderá demorar muito tempo. Não sei exatamente o que Eli quer dizer; É ISTM que, se você tiver memória suficiente, tudo ficará bem, mas ele é o especialista aqui.

Dito isso, já usei essas linhas no meu arquivo init por um tempo e ajuda a reduzir o tempo de inicialização sem tornar as alterações 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
fonte
Por que você não usa after-init-hook?
Erik
3
Porque isso seria executado imediatamente após a inicialização, o que pode fazer o usuário esperar pelo GC. Usando um timer ocioso, ele pode ser executado quando o usuário não estiver usando o Emacs.
blujay