Що я можу зробити, щоб прискорити запуск?


41

Які основні речі я можу зробити, щоб скоротити час запуску?

Чи є щось, на що я мушу звернути увагу з цього приводу?

Примітка. Час запуску можна зменшити, запускаючи Emacs рідше (один раз на сеанс) та відкриваючи файли у запущеному екземплярі . Це питання стосується мінімізації часу запуску, для початку сеансу або будь-якого іншого часу, коли необхідно запустити Emacs.


Дивіться також те саме запитання, на яке було відповідено на стек-переповнення, з балами запитань та відповідей понад 50 та 30 - деякі "улюблені" закладки. Хороші відповіді тут повинні виходити за рамки того, що доступно для переповнення стека.


1
Я хотів би мати дані про це, але я здогадуюсь, що для більшості користувачів є один або два пакети, що становить основну частину часу запуску. У моєму випадку це було кермо. Зауважте, що якщо ви використовуєте штурвал, ви не можете реально відкласти його ініціалізацію, ви хочете, щоб вона була готова використати відразу. Я перейшов на плющ, і це знизило час початку від приблизно 12 секунд до менш ніж секунди. Я навіть перестала використовувати налаштування сервера / клієнта. (До речі, я не перейшов на скорочення часу запуску, це була лише приємна побічна користь.)
Омар

Відповіді:


43

Ось мої моменти щодо скорочення emacs-init-time, це не стосується таких речей, як використання демона або сервера, не можна сказати, що ви рідко коли-небудь повинні закривати emacs.

Не:

  • Не вимагайте пакунків у своїй програмі init, якщо в пакеті немає належних файлів cookie для автоматичного завантаження, переконайтеся, що ви налаштували автозавантаження на команди введення. Тож якщо ви вперше скористаєтесь пакетом foobar, зателефонувавши foobar-modeі foobarне був попередньо завантажений, вам знадобиться щось подібне:

    (autoload 'foobar-mode "foobar")
    

    це дозволить вам зателефонувати foobar-modeнавіть тоді, коли foobarпакет ще не завантажений. Цей спосіб foobarне завантажиться, поки ви фактично не зателефонуєтеfoobar-mode

  • Не запускайте, package-refresh-contentsякщо вам не потрібно встановлювати пакети при запуску. Якщо у вас є програма init для автоматичного встановлення відсутніх пакетів, розгляньте можливість встановлення аргументу командного рядка, щоб вказати, коли має відбутися автоматична установка.

  • Як і вище, не робіть нічого, що стосується мережі.
  • Не завантажуйте свій desktopinit, якщо ви дійсно цього не хочете.

Зробіть

  • Використовуйте щось на кшталт use-packageкерування вашими пакунками. Це дозволяє легко вказати, що потрібно, що потрібно завантажити пізніше, що автоматично завантажує що і полегшує профілювання вашого init на основі пакету.

  • Чи знаєте різницю між завантаженням теми та її включенням. Коротше кажучи, ви можете завантажити скільки завгодно, але переконайтеся, що ви не вмикаєте більше одного. В ідеалі завантажуйте та вмикайте лише одну тему. load-themeпотрібен необов'язковий аргумент, щоб запобігти включенню теми. Це може бути легко випадково включити кілька тем, які повільно і некрасиво під час запуску.

  • Читте: часто існують великі глобальні режими, які ви хочете завантажити на init, такі речі, як скасувати дерево, автозаповнення, режим ido тощо. Переконайтесь, що функції вводу мають налаштування автозавантаження, а потім запускайте неробочі таймери у вашому init для завантаження пакетів . Я це роблю undo-tree-mode, idoі інші, і ніколи не помічаю затримки, оскільки до того моменту, коли мені потрібно їх використовувати, вони вже завантажені.

    Оновлення: use-package трохи змінився, прочитайте офіційне readme перед тим, як почати використовувати функції таймера.

    Наприклад: якщо ви хочете трохи затримати завантаження, global-undo-tree-modeви можете помістити це у свій init:

    (run-with-idle-timer 1 nil (lambda () (global-undo-tree-mode t)))
    

    Тепер ваш ініт може продовжуватись щасливо і global-undo-tree-modeнасправді не активується доти, доки все інше не буде готове їхати, і ви не за кермом.

    use-packageпідтримує такий тип поведінки, вбудований за допомогою ключового слова: idle. Ось undo-treeконфігурація з мого .init.el:

    (use-package undo-tree
      :idle (global-undo-tree-mode 1)
      :bind (("C-c j" . undo-tree-undo)
             ("C-c k" . undo-tree-redo)
             ("C-c l" . undo-tree-switch-branch)
             ("C-c ;" . undo-tree-visualize))
      :ensure t)
    
  • Профілюйте свій ініт, завжди дивно бачити, де справжні повільні падіння. profile-dotemacs.el - це неймовірний інструмент, який я використовував, щоб допомогти мені зняти свій ініт з ~ 6 секунд до <1 секунди.

Добре налаштований use-packageініт може бути неймовірно швидким. Я не виконую байт-компіляцію свого init, і він використовує use-packageдля налаштування 95 пакунків і запускається через <1 секунду.


7
"Профілюйте свій ініт, це завжди дивно, коли ви бачите, де реально сповільнені падіння". Оповіщення спойлера, це та (require 'org)лінія. :-)
Малабарба

@ Джордане, чи не могли б ви трохи розширити, як ви гарантуєте, що функції введення мають налаштування автозавантажень, а потім запустіть непрацюючі таймери у вашій програмі для завантаження пакетів, зокрема для скасування дерева? Спасибі.
Франсіско Дібар

@FranciscoDibar Я оновив свою публікацію прикладами.
Джордон Біондо

2
Я використовую ido-режим негайно, Cx Cf або Mx для smex - це перше, що я майже завжди відкриваю emacs, і я ніколи не помічав проблеми. Також якщо ви хочете щось скасувати протягом секунди після відкриття emacs ... Ну, я нічого про це не можу сказати. Якщо ви насправді так заклопотані, спробуйте це самостійно або просто скористайтеся таймером, що не працює, або після гачка init.
Джордон Біондо

1
Пропозиція таймера в режимі очікування корисна. Трохи коротший синтаксис завантаження - це (run-with-idle-timer 1 nil #'global-undo-tree-mode)'. If the function you are loading takes parameters you can just provide them after the команда # ''.
Ендрю Сванн

8

Щось, що нещодавно з’явилося на reddit emacs : зменшіть кількість викликів для вивезення сміття, поставивши це біля початку вашого файлу init:

(setq gc-cons-threshold 50000000)

(add-hook 'emacs-startup-hook 'my/set-gc-threshold)
(defun my/set-gc-threshold ()
  "Reset `gc-cons-threshold' to its default value."
  (setq gc-cons-threshold 800000))

У наведеному вище прикладі GC викликається кожні ~ 50 Мб (замість за замовчуванням ~ 800kb), що здається розумним у сучасній системі з великою кількістю оперативної пам’яті.


1
За винятком того, що значення (а), ймовірно, набагато вище, ніж вам потрібно (я не бачу різниці з десятою частиною цього); та (b) очевидно не є значенням, яке ви хочете зберігати і після запуску, оскільки великий поріг GC дорівнює більш тривалим затримкам, коли GC відбувається. Якщо ви встановите високий рівень для init, поверніть його знову нижче після init. Я думаю, що emacs-startup-hookце гарне місце для цього.
філс

1
@phils Дякую! (a) Після мого налаштування 50Mb дає мінімальну кількість GC (і мінімальний час запуску). Якщо я досягну 10 Мбіт, різниця помітна / вимірювана (хоча це практично не змінюється ...) (б) хороша ідея, дякую. Я відредагував публікацію, щоб відобразити ваш коментар.
ffevotte

6

Час, який ви витратите на оптимізацію свого часу запуску, швидше за все, буде більшим, ніж увесь додатковий час, якого б ви інакше чекали запуску Emacs.

На даний момент я здійснюю 25 requireдзвінків у своєму файлі init, щоб Flycheck міг знайти орфографічні помилки в моєму коді. Мій час запуску - ...

$ time emacs --eval '(save-buffers-kill-terminal)'

real    0m2.776s
user    0m2.305s
sys     0m0.148s

Крім того , в моїй системі, time emacs -Q --eval '(save-buffers-kill-terminal)'є realз 0m0.404s. Максимально теоретичний час, який я можу заощадити, становить 2,3 секунди.

Скажіть, що я витрачаю годину, роблячи питання оптимізації свого файлу init. (Я не буду рахувати додаткові 15-30 хвилин, витрачені на більш пізню дату, намагаючись з'ясувати, чому мої зміни не набрали чинності через те, що мій файл init будується в байті.) (Я також не буду рахувати час, який Flycheck врятував би мене в налагоджувачі, якби я не видаляв requireдзвінки.) За годину є 3600 секунд, тож якщо мені вдалося зберегти цілі 2,3 секунди, моя інвестиція в час окупиться лише після 1565 стартапів.

Якщо припустити, що я перезапускав Emacs 3 рази на день, щодня, це займе півтора року, щоб ці інвестиції окупилися. Якби я залишив той самий екземпляр Emacs, який працює протягом декількох днів (як я часто це роблю), я, мабуть, перезапускаюсь лише 2-5 разів на тиждень, і в цьому випадку для погашення цієї інвестиції знадобиться від 6 до 15 років.

Я щедрий, тому що ви, ймовірно, витратите більше години на оптимізацію запуску, і ви, мабуть, не збережете максимальну теоретичну кількість секунд.


12
Але ви потенційно будете щасливішими.
філс

2
Це може бути правдою для однієї людини, але вся суть StackExchange полягає у спільному використанні. А як з трюком, який потребує 30 хвилин для пошуку однієї людини, але голить 1 секунду від часу запуску десятків людей? Ви все ще вважаєте це поганою інвестицією?
ffevotte

@phils Як не дивно, я вважав, що я кажу те саме, але на підтримку моєї власної точки зору! "Перш ніж затурбуватися про час запуску, подумайте про себе:" Я радий, що не витрачав час на оптимізацію! ""
Джексон,

@Francesco І ця публікація - мій трюк, який економить час десяткам людей.
Джексон

@ Джексон, я все ще не згоден з вами в цьому конкретному питанні, але принаймні зараз я бачу вашу думку. Дякую :)
ffevotte
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.