Подтвердить что ты не робот

Недостатки использования INLINABLE прагмы

Я задаю этот вопрос в надежде уточнить ответ, который Симон Марло дал предыдущему вопросу о INLINABLE, связанном здесь:

Есть ли причина не использовать прагму INLINABLE для функции?

Я понимаю, что это почти дубликат этого вопроса, за исключением того, что Саймон Марло не ответил на ключевой вопрос, который имеет значение для большинства авторов библиотек: безопасно ли оно с точки зрения производительности просто добавить INLINABLE прагмы ко всему?

Насколько я могу судить, единственными недостатками являются:

  • Более медленное время компиляции

  • Более крупные файлы интерфейса (т.е. *.hi)

Но я действительно хочу знать, будет ли код работать медленнее в результате добавления INLINABLE прагм? Другими словами, может ли прагма INLINABLE когда-либо заставлять GHC выбирать менее оптимальную оптимизацию?

Причина, по которой я спрашиваю, заключается в том, что многие авторы библиотек, включая меня, не заботятся о размерах файлов интерфейса, и мы не наблюдаем значительного замедления компиляции при добавлении INLINABLE прагм, поэтому он соблазнительно просто рефлексивно добавьте их повсюду, поскольку, как представляется, нет никакой платы за это.

И наоборот, стоимость их исключения заключается в том, что когда модули становятся очень большими ghc начинает выборочно пропускать некоторые функции из файла интерфейса для экономии места, что иногда приводит к худшей оптимизации, и очень трудно предсказать на в какой точке это произойдет и какие функции он опустит.

Я лично никогда не наблюдал, как функция работает медленнее в результате аннотации INLINABLE, но это может быть полностью связано с удачей. Если есть случаи, когда INLINABLE замедляет работу, я хотел бы знать, почему он делает это, чтобы я мог лучше рассуждать о том, когда добавлять прагму, а не утомительно сравнивать каждую перестановку прагм. Компилятора.

4b9b3361

Ответ 1

Не уверен, что это относится к чисто функциональной перспективе, и это, безусловно, не полный ответ на ваш вопрос, но он один бит.

Из точки управления или представления системы, делая все INLINEABLE означает, что каждое крошечное изменение любой функции заставляет интерфейс изменять, и вы получаете новый идентификатор пакета и должны перекомпилировать все в зависимости от этого модуля.

Это, например, вызывает проблемы для дистрибутивов: мы пытаемся выполнить резервное копирование исправлений безопасности в пакет в стабильном Debian. Если исправление не изменяет ABI, мы можем просто обновить один пакет (и перестроить все статически созданные программы). Если он изменит ABI, нам, возможно, придется перестроить пакеты dozends или более. Такие проблемы позволяют Haskell выглядеть плохо тем, кто должен справляться с проблемами, но кто не заботится о Haskell в частности.