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