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