Как стать автором
Обновить

Комментарии 10

Вы наверняка объяснили это в предыдущих статьях, но я, быстренько пробежавшись, не нашел ответа. Насколько я помню в vim можно писать плагины на питоне. Зачем тогда vimscript, дело в скорости?
Если дело в скорости, то писать нужно на чём угодно, кроме vimscript.

Дело в том, что Vim можно скомпилировать так, что в нём не будет поддержки Python. Но нельзя так, чтобы в нём не было поддержки vimscript (хотя можно так, что vimscript там будет, но 99 % дополнений работать не будут).
Если хорошо постараться, под Vim можно писать на любом языке, но я так не люблю зависимости ((
Скрипты vim всегда пишутся на vimscript, а внутри vimscript можно вызывать python командой :py
И все же, как со скоростью? Вызов внешнего интерпретатора дает выигрыш? Есть объективные оценки? Что показывает ваш личный опыт?
Скрипты vim всегда пишутся на vimscript

Совершенно верно.

Вызов внешнего интерпретатора дает выигрыш?

Объективных оценок не делал, но опыт есть.
Если подойти к делу с умом, воспользоваться потоками при парсинге проекта и подобных, тяжелых операциях, то выигрышь явный. Проблема в том, что далеко не везде можно этим воспользоваться, так как на скорость сильно влияют все подключаемые плагины редактора, а не только один конкретный, и часто эти плагины настолько просты, что с помощью того же питона не сильно то оптимизировать получится. Возьмем к примеру плагин для вывода в качестве стартового меню списка последних рабочих проектов. Все что нужно этому плагину для работы, это один файл с этим списком, который будет считываться при старте редактора и отображаться. Что тут оптимизируешь? А вот когда подобных плагинов появляется десяток, то система начинает заметно тормозить на старте.

Другая проблема это инициализация плагинов при старте редактора. Ведь чтоб они заработали интерпретатору нужно распарсить их скрипты и выполнить их. Не думаю, что использование стороннего языка сколько нибудь облегчит эту операцию. Я уповаю здесь на lazy load и активно его применяю. Благо в Vim есть механизм autoload кода, позволяющий подгружать код при его первом использовании, это сильно облегчает старт редактора. Именно поэтому я основную логику плагинов выношу в autoload. Эта модель еще не полностью мной реализована, есть над чем работать, но в голове уже решение имеется.

Резюмировав вышесказанное: от сторонних языков есть толк при реализации сложной логики, которая не может быть разделена на мелкие составляющие и выполняться при первом использовании (типа парсинга всех файлов проекта, поиска в проекте и любых тяжелых, но атомарных операциях). Во всех остальных случаях VimScript себя показывает хорошо, если правильно разложить файлы плагинов и максимально использовать lazy load.
Lazy loading работает вне зависимости от того, на чём написано дополнение. На парсинг использование не‐VimL влияет сильно: в Vim нет парсера, код исполняется напрямую. В ряде случаев он исполняется с флагом, говорящим, что делать ничего не нужно (к примеру, в случае с if, когда условие не выполняется), но в любом случае ни AST, ни байткода просто нет. Соответственно, с одной стороны, нет кэшей вроде *.pyc даже внутри самого Vim и исполняться всё будет намного дольше, с другой стороны добавление вещей вроде AST и байткода замедлит выполнение всего, что выполняется один раз, т.к. придётся тратить ресурсы на различные преобразования, при однократном исполнении излишние.

Ещё конкретно function A()…endfunction будет обработано быстрее, чем Python обработает def a():… (возможно, даже в байткоде), т.к. текущий «парсер» просто ищет строку с endfunction, даже не пытаясь как‐либо интерпретировать тело функции.

Переписыванием на Python или на другой язык можно оптимизировать практически любое дополнение, функциональность которого используется 50 и более раз, но если эта функциональность и так отрабатывает менее, чем за 100 мс, то зачем что‐то делать, если никто не увидит разницы? Плюс время старта интерпретатора поднимает минимальное количество использований для того, чтобы оптимизация являлась оптимизацией.

Именно поэтому на не‐VimL пишут, когда

  1. Нужно запускать что‐то тяжёлое.
  2. Нужно делать что‐то асинхронно. Обычно является следствием первого пункта. Недавно добавленные каналы тут могут помочь в ряде случаев остаться на чистом VimL.
  3. Нужно использовать сторонние библиотеки.
  4. Нужно написать дополнение для более, чем одного редактора.

В списке отсутствует «не хочется тратить время на изучение VimL», поскольку тратить его придётся при использовании любого языка. В текущем состоянии даже переход на Neovim с его API не поможет.
Lazy loading работает вне зависимости от того, на чём написано дополнение

Я и не утверждал обратное.

но если эта функциональность и так отрабатывает менее, чем за 100 мс, то зачем что‐то делать, если никто не увидит разницы?

Верно. Потому не рекомендую все писать на питоне.
Нужно делать что‐то асинхронно.
Уточните, пожалуйста. Внешний код ведь вызывается из viml скрипта, который блокирует всегда by_design. Кажется основная цель проекта neovim решить это и обеспечить неблокирующее исполнение скриптов. Что вы подразумеваете под async?
В VimL нет никаких способов создать новый поток и что‐то сделать в нём. До недавнего времени даже нельзя было вызвать процесс и продолжить работу, не дожидаясь его завершения. В Python можно и то, и то. Так что то, что внешний код вызывается из VimL скрипта абсолютно ничего не говорит о его синхронности.
Единственное но: вы можете создать новый поток из Python и заставить его делать некоторую работу, но он обязан не вызывать собственные функции редактора. По крайней мере, не заблокировав перед этим основной поток (для чего встроенных функций нет; или не было, я не смотрел код каналов; в любом случае если и есть, то в Python binding’ах они не используются). В Neovim такой проблемы быть не должно, т.к. «внешние» запросы попадают в очередь, исполняющуюся вполне себе синхронно.

Это не мешает, делая «тяжёлые» вычисления в неосновном потоке сохранять результаты в недрах интерпретатора Python, откуда их будет тянуть основной поток. GIL Python’а Vim не блокирует, так что всё будет полностью параллельно, пока основной поток не воспользуется Python интерфейсом.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории