I am working on a project right now, where I am dealing with Prim typeclass, and I need to make sure that the specific function that I wrote is specialized. That is, I need to make sure that when I call it, I get a specialized version of a function in which Prim dictionaries get into specialized dictionaries instead of passing them at runtime.
Fortunately, this is a pretty well-understood thing in the GHC. You can simply write:
{-
And in my code this approach works fine. But, since open, there may be instances of Prim , which I still don't know about when the library is written. This brings me to the problem. GHC User Guide SPECIALIZE documentation provides two ways to use it. The first puts SPECIALIZE in the definition site, as I did in the above example. The second is by placing the SPECIALIZE pragma in another module where the function is imported. For reference, an example provided by the user manual:
module Map( lookup, blah blah ) where lookup :: Ord key => [(key,a)] -> key -> Maybe a lookup = ... {-
The problem I am facing is that this does not work in my code. The project on github , and the corresponding lines:
To run the test, run the following commands:
git submodule init && git submodule update cabal new-build bench && ./dist-newstyle/build/btree-0.1.0.0/build/bench/bench
When I run the test as is, there is a part of the output that states:
Off-heap tree, Amount of time taken to build: 0.293197796
If I uncomment line 151 from BTree.Compact , this part of the test runs fifty times faster:
Off-heap tree, Amount of time taken to build: 5.626834e-2
It is worth noting that the modifyWithM function in modifyWithM is huge. This is an implementation of over 100 lines, but I don't think this should make a difference. Documents state:
... mark the definition of f as INLINABLE, so that the GHC guarantees that the spread can be opened no matter how big it is.
So, I understand that if the specialization on the definition site works, it should always be possible to specialize on the call site. I would appreciate any ideas from people who understand this mechanism better than I do, and I would be happy to provide more information if something is unclear. Thanks.
EDIT: I realized that there is a problem with the reference code in the git declaration I am associated with in this post. It repeatedly inserts the same value. However, even after fixing the problem, specialization is still happening.