haskell inline ghc pragma

haskell - ¿Hay alguna razón para no usar el pragma INLINABLE para una función?



inline ghc (1)

La documentation dice:

Un {- # INLINABLE f # -} pragma en una función f tiene el siguiente comportamiento:

  • Mientras INLINE dice "por favor encuéntrame", el INLINABLE dice "siéntete libre de ponerme en línea, usa tu discreción". En otras palabras, la elección queda en manos de GHC, que usa las mismas reglas que para las funciones sin pragma. A diferencia de INLINE, esa decisión se toma en el sitio de la llamada y, por lo tanto, se verá afectada por el umbral de entrada, el nivel de optimización, etc.

  • Al igual que INLINE, el pragma INLINABLE conserva una copia del RHS original con fines de delimitación, y lo conserva en el archivo de interfaz, independientemente del tamaño del RHS.

  • Una forma de usar INLINABLE es junto con la función especial en línea (Sección 7.18, "Funciones especiales incorporadas"). La llamada en línea f intenta forzar la entrada en línea f. Para asegurarse de que f puede estar en línea, es una buena idea marcar la definición de f como INLINABLE, de modo que GHC garantice exponer un despliegue sin importar cuán grande sea. Además, al anotar f como INLINABLE, se asegura de que la RHS original esté en línea, en lugar de cualquier versión optimizada aleatoria del optimizador de f GHC.

  • El pragma INLINABLE también funciona con SPECIALIZE: si marca la función f como INLINABLE, puede posteriormente ESPECIALIZAR en otro módulo (consulte la Sección 7.16.8, "SPECIALIZE pragma").

  • A diferencia de INLINE, está bien utilizar un pragma INLINABLE en una función recursiva. La razón principal es para permitir el uso posterior de SPECIALIZE

¿Cuál es la desventaja de eso?

¿Hace los archivos de interfaz mucho, mucho más grandes? ¿Hace la compilación mucho más lenta?

¿Hay alguna razón por la que no deba poner un pragma ININTERNO en cada función exportada que escribo? ¿Hay alguna razón por la cual GHC no pone un pragma ININTERNO en cada función exportada que escribo?


Hay tres diferencias entre usar INLINABLE y no usar un pragma en absoluto:

  • Sin INLINABLE, la definición que figura en el archivo de interfaz es el código después de la optimización, mientras que con INLINABLE, es el código que escribió (más o menos). En particular, sin INLINABLE, GHC podría incluir otras funciones en la definición de la función.

  • Sin INLINABLE, GHC omitirá la definición del archivo de interfaz si es demasiado grande. Si alguna otra función se introdujera en el lado derecho, esto podría llevarlo fácilmente más allá del límite.

  • INLINABLE también activa una maquinaria inteligente que se especializa automáticamente en las funciones sobrecargadas donde se usan, y comparte las versiones especializadas con otros módulos que importan transitoriamente el módulo en el que se creó la versión especializada.