В ЯОС профайлер вызывается через пункт меню "Диагностика/Профилирование", в оригинальной A2 всё это называется по-английски, как - я уже не помню. В любом случае, открывается окно, озаглавленное Profiler. Правда, чтобы он заработал достаточно хорошо, нужно пропатчить код. Я работаю под Win32, и нужно применить вот такой патч, не спрашивайте меня, почему - я сам не знаю, но в ЯОС я его уже применил. Если вы используете оригинальную A2, то это нужно сделать вам.

https://gitlab.com/budden/jaos/-/commit ... c3a5e9fa2f

Так вот, запускаем профайлер, нажимаем Start, выполняем нужное действие, потом Stop, потом Get profile. Появляется дерево вызовов с долями времени, которое выполнение находилось в этом (или таком же по форме стека?) узле. Сумма может превышать 100, т.к. активностей больше одной.

Нажав на любом узле кнопку Flatten, можем получить суммарное время по процедурам, уже независимо от стека вызовов.

С помощью этих нехитрых действий, повторённых с должной настойчивостью, я убедился, что функция LazySweep занимает 98% времени моей задачи. А LazySweep - это часть сборщика мусора.

Дальше я опять обратился к Сергею и он ещё раз помог советом. Нужно запустить
WMPerfMonPluginHeap.Install ~ и посмотреть в Системное меню->Inspect->Perfomance->Plugins->NewBlocks

ну и там же GcRuns

На каждом из этих показателей я нажал "Graph", потом запустил компиляцию и получил картинку, которая последует ниже. Она показывает, что во время компиляции выделяется много памяти, но это происходит быстро. А вот затем выделяемая память растёт очень медленно, зато постоянно начинает вызываться сборка мусора.

Как только я отправил Сергею эту картинку, я решил снабдить её и фрагментом кода. Но, почитав код ,я уведил, что я более тысячи раз выделяю объект размером в 1 мегабайт, который служит для вывода буквально нескольких знаков на печать, после чего уничтожается.

Дальше возникло очевидное решение: выделять не 1 мегабайт, а столько, сколько надо. Благо, в А2 есть объект Strings.Buffer, который как раз "резиновым" по размеру буфером текста, умеющим увеличиваться. У буфера есть поток вывода, в который можно писать, его можно получить методом GetWriter. Таким образом, каждый раз выделять его сразу размером в мегабайт не имело никакого смысла. Размер является параметром конструктора данного объекта. Как только я стал создавать Strings.Buffer размером в 16 знаков, данный этап вычисления стал проходить молниеносно.

Что можно сказать? Нужно поблагодарить Сергея за его непрекращающуюся, несмотря на все мои взбрыкивания, помощь, надеюсь, так будет и впредь. И отметить, что в A2/ЯОС есть хороший набор инструментов для мониторинга, с помощью которого можно многое продиагностировать и локализовать многие проблемы.

В рамках данной статьи пока что разница между ЯОС и A2 несущественна. Там, где она есть, я её оговорил.