Мои мысли насчет IDE и прочих developer tools

Поскольку я 5+ лет провел в JB, конторе которая пилит IDE, у меня накопилось много опыта и мнений насчет того как эти «ИДЕ» стоит строить. Сразу скажу, что непосредственно в разработке IDE я практически не участвовал — как я уже говорил, в JB я попал в то странное время в моей жизни, когда на «карьеру программиста» мне было чуть более чем совсем, так что становиться кодером и слить 10+ лет жизни за весьма-весьма скромные деньги я не планировал.

Тем не менее, у JB в плане сред разработки есть хорошая, отработанная, модель. Нужно понимать что JB ультраконсервативен — подход всегда один, он идет под копирочку: если есть язык с неким спросом, то на базе IDEA делается IDE которая реализует все то же, что реализовали другие IDE. Кумулятивный опыт дает это сделать быстро и эффективно, а фишечки вроде Котлина дают это сделать еще и приятно (т.к. Java — это фифифи, никто не хочет об нее руки пачкать).

Так вот, после наблюдений за всей этой кухней, у меня сложился свой собственный набор мнений относительно того как надо это делать, что работает а что не работает. Вот список того что мне приходит на ум.

Аппаратно ускоренный редактор

Знаете, мы вот в алготрейдинге не пишем терминалы для обычной виндовой консоли. И оконных приложений не пишем. Почему? Да потому что скорость, что у обычной текстовой консоли (cmd.exe итп) что у оконных приложений — просто шлак. Они тратят больше времени на отрисовку чем на обработку потоков данных. Да, это конечно няшно что виндовая консоль потокобезопасна, но я такое же запилил на коленке, с множественными viewport-ами и буферами. Я на этом собаку съел.

А как надо, спросите вы? Да все просто. Рисуем текстурку на которой ровно 256 буков, ибо использовать юникод не нужно, а языки вроде русского (прости хосподи MOEX) вполне себе в эти 256 влезают. Так вот, на тестурке рисуем каждую из буков, а потом из этой текстурки рендерим каждую букву как прямоугольник на 2D полотне, со всем прекрасным аппаратным ускорением которое нам дают дорогущие видеокарты.

Зачем все это? Да потому что нужна скорость. И она нужна везде. Это бред когда ты редактируешь текст в ИДЕ и у тебя suka залип текстовый редактор! Это просто тотальный бред! Я понимаю что залипания там по вине всяких комплишнов, и что все IDE постепенно прут к zero latency, но я хочу чтобы для рисования одной отдельно взятой буквы не возбуждались, например, подсистемы интерпретации содержания шрифтов. Какая-нть GDI которая делает DrawText() сливает перформанс настолько, что это даже не смешно, это все тотальный позор.

Кто-то скажет «а как же юникод?» — да в гробу я его видал. Если вы вдруг определили символ дерева через kanji или засунули в код смайлик, мне вас не жалко вообще, используйте Visual Studio или IDEA или что у вас там. И продолжайте лелеять мысль что у вас там «аппаратное ускорение». Ага, щас.

На самом деле, плюсов от текстурно-ориентрированного текст редактора миллион — это в том числе и идеальная плавность скроллинга, возможность очень плавного движения курсора и так далее. Кстати, в моих последних видеокурсах это все представлено как некий рендер — можете посмотреть там превьюшки, и это не предел фантазии!

Короче о чем я — редактирование нужно упрощать и делать аппаратным полностью. Реально много крутого можно сделать, но самое главное это то, что скорость отрисовки феноменальная!

Языковые и source-сервисы

IDE и анализ IDE должны быть разорваны. Ни сервис анализа кода, ни сами сорцы не обязаны лежать локально. И с тем и с тем можно работать удаленно, ибо скорость сетей такая что никакого особого лага не будет. Rider кстати оторвал анализ от редактора, и сделал это весьма успешно через кастомный асинхронный протокол. Но эту идею нужно «дожать» и вынести нафиг это не в отдельный процесс, а в отдельный процесс который может быть где угодно в сети.

Это часть задачи. Другая часть — это сделать весь этот процесс распределенным. Идея о том что только один комп анализирует код, например, или компилирует, или тестирует — это достаточно бредовая идея. Нужная полная распределенность во всем. У нас уже есть примеры вроде IncrediBuild который раскидывает компиляцию по сети, то же самое нужно делать и с анализом и прочими вещами.

Выбор языков программирования

То, что JB сделали все на джаве и сишарпе — это одновременно огромный плюс и огромный косяк. Фразы про «решарпер тормозит» я слышал 5 лет подряд. Если бы в то время не изобрели SSD, вся эта кухня вообще застряла бы в оптимизациях, т.к. на обычных жестких дисках работать со всей этой хитрой инфраструктурой невозможно вообще. Над перформансом там работают постоянно и это, с одной стороны, хорошо, но с другой стороны отчасти виноваты те платформы которые были выбраны для всего этого — JVM и .NET.

В high-performance среде очень важен детерминизм. Вы напарсили 10000 файлов и наплодили временных объектов — кто их будет удалять, и когда? По личному опыту я знаю, что когда нужен перформанс, ты начинаешь жестко копаться во всяких ref struct, пинить массивы и еще 100500 непотребных вещей.

Да, С++ тяжелый язык и в нем много косяков. Но на нем блин самолеты летают и танкеры плавают! Да, бывают проблемы, язык не совершенен, предостаточно странных решений и немного муторный процесс стандартизации.

Но С++ дает тебе «честные» деструкторы. Он дает как ручной контроль памятью (иногда бывает нужно), так и возможность использовать «умные» указатели. Это намного более предстказуемо чем взять и нааллоцировать тысячу мелких объектов и потом жаловаться что GC делаеть stop-the-world как раз в тот момент когда пользователь пытается вызвать какойнть компшишн.

Еще одна «фишечка» в том, что уйдя на управляемые платформы, мы сразу теряем доступ к таким вещам как микрооптимизации. Такие вещи как использование SIMD или Assembler-ных вставок позволяют реализовывать некоторые вещи не в десятки, а в сотни раз быстрее! Сколько бы не говорили производители этих рантаймов, что JIT заоптимизирует ваши циклы, это все наглая ложь!!! Автоматизация этого происходит только на самых тривиальных, «детских» циклах где все очевидно. Когда у вас появляется хотя бы малейшая зависимость, ваша параллельная или SIMD-овая карета превращается в тыкву.

Особняком стоит ситуация со строками, что какбэ актуально, т.к. в .NET строка — это немутабельная UTF16 конструкция. Это совершенно непрактично по ряду причин. Во-первых, инвариант sizeof(char) == 1 дает возможность детерминированно обходить ASCII-буквы без извратов. То есть, вы прикинули ситуацию? У вас в 99.99999999% случаев только ASCII в коде, но вы платите огромную таксу за то что System.String реализует весь свой API c допуском что там может быть всякие юникодные corner-cases.

По секрету скажу, что в дотнете у меня для алготрейдинга просто написан тип Str — это как string но он строго ASCII, просто держит массив байтов. Естественно, всякие Contains() становятся вообще тривиальной задачей.

Что еще хорошего от однобайтовых ASCII строк? Да то что они очень хорошо ложатся на GPU. И если вы думаете что GPU тут неприменим, вы просто не научились его готовить — если держать список строк в прямоугольном массиве памяти (представьте себе буфер редактора, ограниченный по горизонтали), то внезапно можно весь этот кусок памяти через P/Invoke скормить CUDA, которая на нем сможет делать такие банальный, казалось бы, вещи как Search & Replace. Это работает не просто «хорошо», это работает офигенно. Особенно на крупных проектах, с которыми, как вы знаете, у всех IDE огромные проблемы, которые не лечатся закупкой RAM-а.

Я могу еще долить про строки если хотите. Помимо юникода, есть еще такая проблема как немутабельность. В частности, эта проблема заставляет многих разработчиков реализовывать свой Substring(), т.к. фабричный порождает новые строки, а если вам просто хочется некий эфемерный StringRange, вам придется приготовить его самим, со всеми операторами, конверсиями, набором методов и прочей кухней. Заметьте — вы можете передать ref string в метод, но вы не можете записать адрес строки в поле. Можно долго извращаться со всем этим, но потом ты понимаешь, что даже со всем запредельным бредом в АПИ, std::string не так уж и ужасен.

Вообще, в большинстве случаев, мы все равно пишем свой str (печатать string слишком долго). Суть заключается в том, чтобы сделать нужные операции как можно дешевыми. В качестве «кустарного» примера можно посмотреть на folly/fbstring.

Аппаратное ускорение

Если мы с вами договорились, что редактор и сорцы/анализ должны находиться в разных местах, то кто мешает на бэк-энде пошаманить еще в направлении анализа кода и всего вот этого? И я сейчас не столько про всякие Optane-ы (хотя хорошее железо тоже нужно), а скорее про специализированные решения в области анализа.

Например, почему бы не загрузить весь working set разработчиков вообще в оперативку? Ну, подумаешь съест там сколько-то гигов на разработчика, всяко анализ пойдет легче пока вам не нужно копать файловую систему со всеми ее ACLами и прочими прелестями. Это кстати и компиляцию тоже ускорит существенно, если что — я например до сих пор, несмотря на то что 2019й на дворе, компилируют крупные вещи вроде Boost на RAM-диске. Ибо нефиг.

Еще одна фишечка это GPGPU, про которые я уже упомянул. Более того, можно не только держать прямоугольные массивы строк, можно также держать базы данных прямо на GPU. Это свежая, развивающаяся область, и там очень много интересного, в т.ч. уже сущестуют коммерческие решения. Представьте себе базу данных, которая ищется в десятки/сотни раз быстрее чем даже если бы она была в RAM полностью.

Касательно FPGA — тут тоже много идей. Одна из них в том, что порой на FPGA очень удобно реализовывать структуры данных. Особенно если это не гигантские но performance-critical структуры. Вообще про FPGA должен наверное быть отдельный разговор т.к. это «темная лошадка» всей этой схемы. Я-то конечно научился уже работать с FPGA-картами через шину PCI (нет ничего сложного если у тебя есть правильный софт), но как получить от них максимальный прирост именно с точки зрения анализа и других девелоперский фич — это вопрос. Одна из идей которые достаточно хорошо раскопаны — это лексеры, т.к. лексический анализ это обычно data-intensive проблема которая очень хорошо ложится на эту архитектуру. Другое дело что лексинг — это только часть общего процесса.

Спекулятивные вычисления и машинное обучение

Как показывает мой проект CallSharp, вполне реально «выводить» подходящий код по набору входных-выходных значений. Я кстати планирую эту тулу допилить до нужного состояния и возможно даже продавать ее, т.к. эта штука реально открыла мне глаза на возможности computer-assisted coding, даже в условиях когда ты делаешь банальный перебор.

Машинное обучение конечно должно идти дальше. Например, я считаю что делать тесты для методов руками — это нонсенс. Если есть некий функционал, мы как минимум должны иметь возможность генерировать для него test scaffolding который потом можно заполнять тестовыми данными. This is low-hanging fruit.

Тут очень сложно предсказать, по какому пути все пойдет. Я например огромный фанат суперкомпиляции — подходу, в котором компьютер выводит по нужным данным цепочку последовательностей комманд. Сейчас это делают, в основном, на микро уровне, т.е. на уровне инструкций процессора. Порой результаты просто ошеломляют — ведь в отличии от человека, компьютер будет напрямую использовать всякий bit twiddling (сдвиги итд.) для того чтобы решить задачу эффективнее.

В идеале, хотелось бы достичь такого состояния, когда компьютер не лексит/парсит на основе описания грамматик, а сам начинает изучать поведение компилятора и на основе этого строит наиболее эффективные структуры для разбора и анализа кода. Вот это то, на что я бы очень хотел посмотреть, но к сожалению «а воз и ныне там» и все видимо занимаются другими, более важными делами.

Заключение

Я не исключаю что мне самому захочется позаниматься чем-то связанным с IDE но если я и буду это делать, то абсолютно все каноны современного ИДЕстроительства будут выкинуты в помойку, т.к., в ретроспективе, понимаешь какое количество родовых травм есть у всех этих систем.

Если коротко, то основные фичи — это

  • Аппаратный рендер текста (плавный скроллинг, анимации итд)

  • Разнесенные на отдельные процессы/компы редактор, компиляторы, анализаторы и все такое

  • Выборочное аппаратное ускорение различных девелопер-специфичных процессов

  • Спекулятивные вычисления — непрерывная компиляция, тестирование и все в этом духе

  • Машинное обучение которое помогает кодить и диагностировать такие ошибки, которые обычные тулы диагностировать не могут

На самом деле, самое интересное — это то о чем я не написал, то есть такие парадигмы работы с кодом, которые мы сами и не знаем. У меня есть некоторые… домыслы, например, что ИДЕ должна вывешивать наружу нечто вроде терминала который обрабатывает комманды типа «добавь класс». Думаете бред? А ничего что любой Autocad уже реализует подобное? Почему такое скриптование есть во всяких 3Д системах но его нет в наших ИДЕ — ума не приложу. Надо сделать.

JB сделали три русских парня со стартовым бюджетом в жалкие $300k. Блин, да я $300k хоть сейчас положу на стол если будет полноценное видение всей этой кухни, понимание как ее реализовывать и талантливые кодеры, которые могут все это заимплементить. Ведь мне кажется что все это поле developer tools точно готово к инновациям и disruption.

Короче надо думать. ■

11 responses to “Мои мысли насчет IDE и прочих developer tools”

  1. «и все видимо занимаются другими, более важными делами»? Например, кажущимся им крайне важным делом пропоганды кодинга в блокноте с компиляцией вручную через командную строку. Тех, кто подумывает о том, чтобы двигать воз, яростно пристыжают, потому что «нефиг заниматься ерундой» и «уже все и так идеально, делайте что-нибудь реально полезное».

    Сложно сказать, вытекает ли это из общечеловеческой склонности считать любую мета-работу ерудной, или в этом виноват конкретно Google с огромным влиянием его культуры (см. культуру и в основании и вокруг Golang) на всю культуру разработки ПО.

    Сорян за бесполезный коммент в духе «кто виноват» (вместо, например, «что делать»), накипело. Еще лет 5 назад накипело, и с тех пор мало что изменилось.

    1. Я совсем ничего не понял.

  2. Интересно, откуда данные про 300к? И это их личные средства? – мне просто любопытно, потому что я без понятия об истории компании.

    Кажется направление в сторону – что-то “у нас работает медленно…. и надо этим заниматься” начинает постепенно выходить в массы. Есть же попытки сделать редакторы, правда это не целые IDE.

    Я суть понял так – у нас есть быстрый, легкий редактор для кода, поверх/рядом/сверху/снизу/слева/справа/под – висят так называемые воркеры(редактор с ними общается через плагины), которые могут быть вызваны из редактора с определенным сценарием, как распределенная компиляция и анализ, langserv, remote debuggers и так далее.
    Соответственно в базе – это просто редактор, подсветка кода и все быстро. А далее настройки, конфигурации и тп, если хотим чего-то специфичного.

    Я понял неверно?

    1. Это публичная инфа, на просторах тырнетов есть достаточно про то как jb стартовал. Это сущие копейки, поэтому не инвесторские деньги а основателей, а сама компания по сий день частная.

      Суть вы уловили. Основная идея чтобы сделать все модульным, внешнепроцессным, и все такое. Конечно какой-то объем фоновых анализов все-таки хочется иметь постоянно работающими. Я тут не только про модульность, но еще и про распределенность, чтобы было можно воткнуть какой-нть “быстрый анализатор” в комп как кусок железа и он сразу ускорял ту или иную фишку.

      Sun Microsystems правда погорел на поставке кастомного, слишком дорогого железа. Так что хз, может с железом и не прокатит.

      1. Если с железом, то возможно придется сильно потом переживать по поводу драйверов. Производители железа не сильно любят открывать свои драйверы, а опенсорс может оставлять далеко не лучшее впечатление от этого всего. (Я просто возможно имею негативный опыт в этом.)

        Сейчас же есть понятие LangServer, получается, что все равно все идет к этому. В смысле идеи того, что оставляем редактор, а делаем коллаборативный сервер, куда может убрать все тяжелые части. К примеру, в недавнем релизе одной тулы для реверс инженерии от одной известной американской конторы – есть именно такое решение, репозиторий правда, но все же.

        Тогда все упирается в согласованный протокол. Я нечто такое проектировал для статического нализа с независимыми воркерами по языкам, UAST\IR для главного анализатора. Но идея не полетела.

      2. Ну, и “одна именитая компания” тоже делала continuous version control в 2013 году, но не осилила его не потому что нехватило технологического ноу-хау, а потому что lack of leadership: кто-то ведь должен драйвить все это безобразие. Само по себе это ничего не значит — лично я просто уверен, что это делать нужно, и рано или поздно это делать будут, это лишь вопрос времени. Будет ли это опенсорс или коммерческое решение это все детали, главное что все сейчас понимают что работать все будет именно так — есть очень тонкий редактор который асинхронно взаимодействует с всякими тяжелыми процессами, локальными и не очень. Протокол этот уже есть т.к. Rider работает именно так.

  3. “добавь класс”… каждый раз описывая какую-нибудь типовую обвёртку, хочется “позвать визарда”, но нет его, какова причина, только ли от лени разработчиков, может это в принципе невозможно понаписать визардов на все случаи жизни ?

    1. Вообще да, это очень странно что такого нет, сразу вспоминается MFC Class Wizard который, вообщем-то, ничего такого особенного не делал, но можно ведь было сделать визард и посложнее. Кстати в Автокаде у комманд есть два режима: один вызывает команду-визард в терминальном (текстовом) режиме где каждый шаг прописывается на клавиатуре, а второй вызывает как раз UI, то есть окно с интерфейсом. Так что на вкус и цвет там все неплохо продумали, плюс терминальные команды очень удобно записывать в скрипт и потом запускать скрипты которые генерят модели.

  4. Shakirov Ruslan Avatar
    Shakirov Ruslan

    Windows Terminal с отрисовкой в DirectX.
    https://devblogs.microsoft.com/commandline/introducing-windows-terminal/

    1. Да но тот факт что там есть поддержка юникода означает, что возможно эффективность всего этого не такая высокая, как хотелось бы. При условии что инфа не льется рекой, перформанс будет ОК даже если нужно будет отрисовывать китайские иероглифы. Но мне не хочется даже думать об этом. У меня даже в дотнете тип str который ASCII-строка чтобы можно было на GPU проще загонять.

      Я немного полистал код, мне его тяжело читать, но папочка /gdi там имеется. И уровень сложности там конечно выше чем то что используется в моей терминальной кухне. Я могу на пальцах объяснить свой терминал, хотя у меня раздельные буферы, вьюпорты и все такое.

  5. Hi, Dmitri. I recalled that a while ago you wrote something about GPU-accelerated IDEs.

    I’ve managed to find this post again and it is still pretty interesting, even though I know nothing about CUDA, GPU stuff, hardware acceleration, etc.

    What do you think about your idea about hardware-accelerated text rendering 4 years later? Were there any successful IDEs utilizing something similar to your ideas?

    Also, I just encounter an idea about the RAM drive for the first time here. What did you use for it? I find the idea to have a virtual RAM drive fascinating!

    Thanks for your articles, it was always a pleasure to read your posts, I still have some on my Kindle.

Оставить комментарий