4 ms·
Interesting, but I have to wonder what the point of his project to reproduce the performance of C++ with Haskell is if he's doing things like replacing (i+1)
by smitherfield 12y ago
Interesting, but I have to wonder what the point of his project to reproduce the performance of C++ with Haskell is if he's doing things like replacing
(i+1)%3
with
(1<<i)&3 for i in [0, 2]
It seems to me like it would be far more human-readable and human-maintainable to simply write it in C++ in the first place.
- falcolas 12y agoAny time you cross the FFI, you start losing things. Specific to Haskell, if you hit the FFI into C++, you have to go through two translation layers (Haskell to C, C to C++) in each direction, losing the ability to quickly identify identify code paths. Not to mention many debuggers and profilers tend to shrug their shoulders in ignorance when the FFI is crossed. If a quick obfuscation in the name of performance can be explained away with a single comment, there's no need to jump over the FFI.
- GFK_of_xmaspast 12y agoI don't know haskell, but I would have expected the c++ end to have been compiled with C linkage, why do you have to have the second jump?
- implicit 12y agoI worked with Chad to write BufferBuilder. We conspired our use of C++ to exclude the C++ standard library. It's basically C with stricter pointer conversion rules.
- chadaustin 12y agoI think falcolas is saying that, since the GHC FFI only supports C functions, if you wanted to expose a C++ API (classes et al) you'd need to have a C trampoline call into C++. But, then again, the compiler might inline the C++ call into the exported C function. Hard to say without trying and looking.
- falcolas 12y agoIt would depend entirely upon whether you wrote all of the C++ code and thus provided yourself with C wrappers inside an `extern c` call. In which case, yes, it would be simpler (though still with an interpreter layer going from C to C++). However, if you use an external library, or you are interfacing with C++ overloaded methods or classes, you have to write an interface inside the `extern c` wrapper which handles calling out to C++ code. Of course, there is always the option of running something like swig to create the C bindings for you.
- chadaustin 12y agoHaskell and that particular div -> shift trick were two unrelated examples. The Haskell one is kind of a long story. In short, we love Haskell but a particular inner loop was destroying our performance. We were getting PHP-level performance in Haskell, where normally we can expect Java-level performance. So we took this inner loop (JSON encoding and URL encoding) and built BufferBuilder to solve it once and for all. Now JSON encoding and URL encoding are barely visible in the timings. The div -> shift trick is worth knowing about, though I haven't had a reason to use it yet.