У меня есть небольшая тестовая структура. Он выполняет цикл, который выполняет следующие операции:Ускоренный runhaskell
Создайте небольшой исходный файл Haskell.
Выполните это с помощью
runhaskell
. Программа создает различные файлы на диске.Обработка только что созданных файлов диска.
Это происходит несколько десятков раз. Оказывается, что runhaskell
занимает большую часть времени выполнения программы.
С одной стороны, факт, что runhaskell
удается загрузить файл с диска, подделать его, проанализировать, выполнить анализ зависимостей, загрузить 20 КБ больше текста с диска, выполнить токенизацию и разобрать все это, выполнить полный вывод типа, проверить типы, desugar to Core, ссылку на скомпилированный машинный код и выполнение вещи в интерпретаторе, всего за 2 секунды времени на стене, на самом деле довольно впечатляюще, когда вы думаете об этом. С другой стороны, я все еще хочу ускорить его. ;-)
Компиляция тестера (программа, выполняющая вышеуказанный цикл) породила небольшую разницу в производительности. Компиляция 20 Кбайт библиотечного кода, связанного с ссылками на скрипты, вызвала более заметное улучшение. Но это все равно занимает около 1 секунды за вызов runhaskell
.
Сгенерированные файлы Haskell имеют чуть более 1 КБ каждый, но только одна часть файла на самом деле изменяется. Возможно, компиляция файла и использование коммутатора GHC -e
будет быстрее?
В качестве альтернативы, возможно, это накладные расходы на многократное создание и уничтожение многих процессов ОС, которые замедляют это? Кажется, что каждый вызов runhaskell
заставляет ОС исследовать путь поиска системы, найти нужный двоичный файл, загрузить его в память (конечно же, это уже в кэш диска?), Связать его с любыми DLL-файлами и запустить его. Есть ли способ (легко) сохранить один экземпляр GHC, а не постоянно создавать и уничтожать процесс ОС?
В конечном счете, я полагаю, что всегда есть API GHC. Но, насколько я понимаю, это кошмарно сложно использовать, сильно недокументировано и подвержено радикальным изменениям в каждом выпуске MH. Задача, которую я пытаюсь выполнить, очень проста, поэтому я не хочу делать вещи более сложными, чем это необходимо.
Предложения?
Обновление: Переключение на GHC -e
(то есть, теперь всего компилируются за исключением того, одно выражения выполняется) не имеет никакого значения измеримой производительности. На данный момент кажется довольно ясным, что это все ОС накладные. Мне интересно, могу ли я создать трубу от тестера до GHCi и, таким образом, использовать только один процесс ОС ...
Весь ваш рабочий процесс не выглядит точно нацеленным на производительность, не так ли? Почему вы должны создать код Haskell? – leftaroundabout
Очевидно, вам нужен демон GHC! : p (некоторые люди, которых я знаю, шутили о создании демона grep, чтобы избежать накладных расходов при вызове grep во время загрузки и т. д.) – ivanm
+1 для обоснованной и хорошо выполненной попытки оптимизации. – delnan