I'm asking this question in hopes of refining the answer that Simon Marlow gave to a previous question about INLINABLE
, linked here:
Is there any reason not to use the INLINABLE pragma for a function?
I realize that this is almost a duplicate of that question, except that Simon Marlow didn't answer the key question that matters the most to many library authors: is it safe from a purely performance perspective to just add INLINABLE
pragmas to everything?
As far as I can tell, the only disadvantages are:
Slower compile times
Larger interface files (i.e. *.hi
)
But what I really want to know is whether code will ever run slower as a result of adding INLINABLE
pragmas? In other words, can an INLINABLE
pragma ever cause GHC to choose a less optimal optimization?
The reason I ask is that many library authors, myself included, don't care about the size of interface files and we don't observe a significant slowdown in compilation when adding INLINABLE
pragmas, so it's tempting to just reflexively add them everywhere, since there seems to be no cost to doing so.
Conversely, the cost of leaving them out is that when modules get very large ghc
starts selectively omitting some functions from the interface file to save space, which does result in worse optimizations sometimes, and it is very difficult to predict at what point this will occur and which functions it will omit.
I've personally never witnessed a function running slower as a result of an INLINABLE
annotation, but that could be entirely due to luck. If there are cases where INLINABLE
slows things down, I'd like to know why it does so that I can reason better about when to add the pragma rather than tediously benchmarking every permutation of compiler pragmas.
Not sure if this qualifies as a purely functional perspective, and it surely is not the complete answer to your question, but it is one bit.
From a system management point or view, making everything INLINEABLE means that every tiny change to any function causes the interface to change, and you get a new package id and need to recompile everything depending on this module.
This is, for example, causing problems for distributions: We try to backport security fixes to package in Debian stable. If the fix does not change the ABI, we can simply update one package (and rebuild all statically built programs). If it does change the ABI, we might have to rebuild dozends packages or more. Such problems let Haskell look bad to those who have to handle the problems, but who do not care about Haskell in particular.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With