Похоже, вы ищете неупакованные массивы. «unboxed» в значении haskell-land означает «не имеет представления кучи во время выполнения». Обычно вы можете узнать, скомпилирована ли какая-то часть вашего кода в распакованный цикл (цикл, который не выполняет выделения), скажем, взглянув на представление core (это очень похожий на haskell язык, это первый этап в компиляции). Так, например вы можете увидеть Int#
в выводе ядра, что означает целое число, которое не имеет представления кучи (оно будет в регистре).
При оптимизации кода на Haskell мы регулярно смотрим на ядро и ожидаем, что сможем манипулировать или корректировать регрессии производительности, изменяя исходный код (например, добавляя аннотацию строгости или перебирая функцию, чтобы она могла быть встроенной). Это не всегда весело, но будет довольно стабильно, особенно если вы закрепляете версию своего компилятора.
Назад к неупакованным массивам: GHC предоставляет множество низкоуровневых примопов в GHC.Prim, в частности, это звучит так, как будто вам нужны изменяемые распакованные массивы (MutableByteArray
). Пакет primitive
предоставляет эти праймеры за немного более безопасный и дружественный API и именно то, что вам следует использовать (и зависит от того, пишете ли вы свою собственную библиотеку).
Есть много других библиотек, которые реализуют распакованные массивы, такие как vector
, и которые построены на MutableByteArray
, но дело в том, что операции с этой структурой не генерируют мусор и, вероятно, компилируются в довольно предсказуемые машинные инструкции.
Вы также можете проверить эту технику , если вы выполняете числовую работу и хотите использовать определенную инструкцию или реализовать какой-то цикл непосредственно в сборке.
GHC также имеет очень мощный FFI, и вы можете изучить, как писать части вашей программы на C и взаимодействовать; Для этой цели haskell поддерживает закрепленные массивы среди других структур.
Если вам нужен больший контроль, чем те, что дают, то, скорее всего, haskell неправильный язык. Из вашего описания невозможно определить, соответствует ли это вашей проблеме (ваши требования кажутся противоречивыми: вам нужно уметь писать тщательно настроенный алгоритм кэширования, но с произвольными паузами в GC все в порядке?).
Последнее замечание: вы не можете полагаться на собственный генератор кода GHC для выполнения какой-либо из низкоуровневых оптимизаций снижения прочности, например, GCC выполняет (NCG GHC, вероятно, никогда не узнает о взломах, авто-векторизации и т. Д. И т. Д.). Вместо этого вы можете попробовать бэкэнд LLVM, но то, что вы видите ускорение в вашей программе, отнюдь не гарантировано.