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


19

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


Час мого запуску Emacs зовсім невеликий. Я не використовую use-package, я просто встановив тонни гачків і autoloadтак, щоб майже весь код був відкладений. Насправді вся справа завантажується зазвичай менше ніж на півсекунди, незважаючи на те, що це здається шаленим безладом.

Однак з часом я помітив, що час мого запуску стає щонайменше повільніше, незрозуміло. Врешті-решт це дійшло до моменту, коли час запуску становить ≥ 1 секунду. Нарешті мені було достатньо, і я вкопався в корені проблеми. Зрештою я прокоментував весь свій ~/.emacsфайл і виявив, що час запуску все ще ≥ 1 секунда. Насправді він лише бривався ~ 0.2секунди, іноді навіть менше. Потім я спробував emacs -qі виявив, що час запуску - ~ 0.1секунди.

Вивчивши цей розділ посібника Elisp, я з’ясував, чому emacs -qнастільки скорочує час запуску. Мабуть, emacs -qзаважає Emacs робити три речі при запуску:

  1. завантаження вашого файлу init
  2. завантаження вашого default.elфайлу
  3. дзвінок package-initialize

Ми вже виключили мій файл init, оскільки коментувати весь мій файл ~/.emacsмайже нічого не робиться. Я не використовую default.elфайл, тому це також виключається. Що залишається package-initializeвинуватцем хіта на виставу.

Чому б package-initializeзайняти стільки часу запуску? Це було перше питання, яке я задав собі. Хіба я не все завантажую автоматично? Ну так. Але що саме ця проблема.

Я знайшов цю публікацію, в якій пояснюється, що "активація" пакунків складається з читання файлів автозавантаження та встановлення шляхів завантаження. Це, очевидно, спричиняє штраф за введення / виведення, коли у вас є багато пакетів, оскільки у вас є багато файлів для автоматичного завантаження, які потрібно прочитати, і встановити багато шляхів. На жаль, без цього завдання управління автозавантаженнями потрапляє до рук користувача. Іншими словами, не дозволяючи package.elсканувати файлову систему для автоматичного завантаження файлів і шляхів, я повинен був би керувати тим, що міг би бути виснажливим і схильним до помилок процесом.

Я вважаю за краще не йти цією дорогою. Наразі я маю 116 пакетів, 107 із них від ELPA, а 25 з них - це залежності. Я впевнений, що це колосальне число - це так сильно принижує мою ефективність. Але я перебуваю в неприємності, бо не хочу видаляти жоден із своїх пакетів.

Чи є такий засіб у такій ситуації, щоб повернути час моменту запуску блискавки?


Оновлення:

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

Ще одне оновлення:

Схоже, що Стефан Моньє вже не цікавиться цим питанням, або він не отримує моїх повідомлень. Я схильний вірити колишньому, що добре, хоча я би вдячний за якусь відповідь від нього, якщо це так. У будь-якому разі, код, який він створив для цього питання, працює досить добре. Найновіші його виправлення можна знайти тут (для Emacs 25.3) та тут (для головного відділення Emacs).Я побачив хороші покращення часу моменту запуску завдяки його патчам, і я перебуваю в тій точці, коли мені комфортно моє час запуску, оскільки він максимально оптимізований, не відриваючи особливості моєї настройки. Я сподівався, що ці патчі в якийсь момент перейдуть на магістраль Emacs, але я здогадуюсь, що мені (або комусь іншому) доведеться зараз взяти за це факел, замість Стефана. У списку розсилки ми розійшлися щодо розподілу авторських прав та ліцензування. Мені спочатку було незручно це робити, але через деякі коментарі Річарда Столмана та інших, присвоєння авторських прав може бути не таким обмежуючим, як я вважав спочатку. Більше того, можливо, я можу зробити свої твори загальнодоступними, як альтернативу авторському призначенню.

У будь-якому випадку, дякую Стефану за патчі поки що! Сподіваюся, ви продовжите розвивати ці зміни, але якщо ні, то це нормально, і я можу продовжувати їх розвивати в якийсь момент. Я також дякую всім, хто запропонував розуміння та внесок у вирішення цього питання.

Ще одне оновлення:

Нічого собі, схоже, що ця функція нарешті висадилася і буде в Emacs 27. Дякую Стефану Моньє!


Чудове запитання.
Дрю

use-packageце шлях для цього.
Доджі

Не намагайтеся применшити проблему (важлива затримка запуску!), Але розглядайте запуск emacs як демон / сервер, так що ви платите за вартість запуску лише один раз.
GManNickG

1
@GManNickG Я запускаю Emacs як сервер. На жаль, раз у раз я надто сильно натискаю Emacs або занадто сильно повозиться, і перезапуск - найкращий спосіб очищення речей. Коли це відбувається, мені подобається, що час запуску буде оптимальним.
ВВП2

Відповіді:


13

Одним із варіантів дизайну в package.el було спробувати зробити речі "простими". Частина цього полягає в тому, що здійснює package-initializeпошук усіх встановлених пакетів, а потім намагається визначити, які саме з них потрібно активувати (відповідно до фіксації та відвідуваності версій у випадку, коли доступно кілька версій одного пакета), а потім завантажується кожен <pkg>-autoloads.elфайл активаційного пакета .

Отже, для N встановлених пакетів, це означає, в основному, читання N <pkg>-pkg.elфайлів з описом пакунків та N <pkg>-autoloads.elфайлів. Для великих НС це може стати серйозною проблемою. Інша потенційна проблема продуктивності полягає в тому, що вона додасть N елементів load-path, тому кожен раз, коли ви loadEmacs здійснюватимете пошук через N каталогів, тому кожен loadбуде сповільнений.

Існують різні способи, як ми можемо спробувати прискорити це:

  • Надайте певний спосіб попередньо обчислити ~/.emacs.d/elpa/package-initialize.el(c)файл, який був би результатом об'єднання всіх прав <pkg>-autoloads.elу правильному порядку. Тоді package-initializeможна просто завантажити цей файл, коли він присутній, і пропустити все інше. Тоді вам знадобиться якийсь спосіб оновити / вимити package-initialize.el(c)файл, коли пакети додаються / оновлюються / видаляються або коли ви змінюєте свій package-pinned-packagesчи свій package-load-list. Я думаю, що це можна зробити за допомогою досить мало змін у системі (єдине, що дійсно потребуватиме змін, я думаю, package-initializeщо це можна сказати "лише активувати", не завантажуючи метадані про доступні пакети).

  • Надайте певний спосіб складання / маніпулювання суперпакетами, тобто пакетом, який поєднує декілька пакетів в один (тому до нього додається лише один елемент load-path, один <pkg>-pkg.elта один <pkg>-autoloads.elзавантажений). Це може бути складніше зробити (адже тоді ви не можете активувати лише частину пакунків, що містяться в таких суперпакетах, тому аналіз залежності / версія може бути складним).

Перший варіант вище повинен бути досить простим у здійсненні та зробить package-initialize набагато швидше, якщо у вас встановлено багато пакетів. Якщо вам цікаво спробувати це, сміливо попросіть мене про допомогу.

FWIW, я щойно намагався створити такий файл мегаавтоматичного завантаження "вручну" на моїй тестовій установці. Результати: час package-initializeзаймає близько 0,9, завантаження mega-autoloads.elфайлу займає 0,3 секунди, що я можу звести до 0,2 сек шляхом прив’язки load-source-file-functionдо нуля і до 0,1 сек шляхом байтового складання файлу. Я чекав кращого прискорення, якщо чесно, але все-таки варто.

[EDIT] Цей підхід "мега автозавантаження" тепер доступний у головній галузі Emacs (щоб стати Emacs-27 у віддаленому майбутньому). Це контролюється новою package-quickstartзмінною.


Це кілька дуже цікавих ідей. Перший звучить більше під землею і менше викликає труднощі. Другий досить цікавий, але це здається роботою для package.elрозробників. Яку пораду ви маєте щодо початку першого варіанту? Мені хотілося б побачити, що я можу з цим вибити, оскільки це здається набагато ефективнішим.
ВВП2

el-get використовує єдиний підхід до автоматичного завантаження файлів, він в основному працює більшу частину часу. Проблема з деякими пакунками, автозавантаження яких залежить від місця розташування у файловій системі, на яку вони оцінюються. Я не дотримуюся того, що ви маєте на увазі під "правильним порядком", хоча чому б порядок завантаження автозавантаження не мав значення (я не думаю, це було навіть детерміновано для поточного пакета.el)?
npostavs

@Stefan, будь ласка, поділіться рішенням, якщо це можливо.
Мануель Уберті

1
@npostavs: Більшість <pkg>-autoloads.elфайлів налаштовує автозавантаження і насправді не хвилює замовлення, але нічого не заважає їм робити випадкові інші речі, а package.el гарантує, що пакет, від якого <pkg>залежить, буде активований перед <pkg>самим собою.
Стефан

1
Чергове оновлення з цього питання: ми почали нову тему в списку розсилки тут і кожен може коментувати або тест з змін Стефана.
ВВП2

6

Проблема, яку ви описуєте про package-initializeвитрату стільки часу для завантаження, - добре відома проблема. Це також одна з проблем, яку деякі рамки emacs намагаються вирішити, завантажуючи автозавантаження вручну.

Я бачу два варіанти вашої проблеми.

  1. Напишіть (або витягніть з фреймворку) функціонал для встановлення шляхів і завантаження автозавантажень пакетів, які вас цікавлять.
  2. Використовуйте рамку, яка явно націлює швидкість. Я особисто рекомендую DOOM emacs . За допомогою цієї програми я завантажую понад 200 пакетів приблизно за 1 секунду.

Одним з головних причин рекомендувати DOOM emacs є те, що рамки встановлюють управління пакетами поза emacs. Не трактуйте мене неправильно, це все-таки emacs, що робить управління пакетами, це просто те, що управління пакетами здійснюється поза стандартним сеансом користувача. Філософія тут полягає в тому, що при нормальному запуску emacs ми повинні мати можливість припускати, що всі пакети присутні і вже можуть бути завантажені. Це економить багато часу. DOOM emacs надає свого роду еквівалент apt-getабо pacmanдля emacs. Після встановлення пакета, щоразу, коли запускається emacs, передбачається, що він уже встановлений; запитань не задавали.


Фу, радий знати, що це питання стосується не лише мене. Дякую, що вказали на DOOM Emacs. Мені доведеться детальніше ознайомитися з цим і побачити, що я можу адаптувати до власної установки.
ВВП2

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