MLton also has perhaps the most impressive performance of any existing functional language implementation. It generates code that easily competes with hand-optimized low-level C/C++/whatever.
MLton can't do SIMD auto-vectorisation, which unfortunately gives it a ceiling significantly below C++ compilers for the sort of thing I do. I generally use FFI calls for chunky, frequently-used vector stuff. It's a good compiler generally.
It can also output to C, similarly. But vectorisable code isn't recognisable as such in the output. I'm pretty sure the compiler that handles MLton's output never sees anything to vectorise.
I don't have measurements to hand, but vaguely speaking, low. Low enough to be worth using for even quite modest calls into vector functions or optimised libraries.
> And can you pass SML function pointers into C code as callbacks?
Yes. At least, you can declare a function statically for export as a callback. You can't pass arbitrary function values.
You can call C/C++ from SML, and call SML from C/C++ from SML - though some neat potential uses are ruled out as MLton (unlike Poly/ML) doesn't support native threads and you can't call back from a different thread from the caller.
You can also compile to a library using MLton and use that from a C/C++ program - again only from a single thread, but it doesn't have to be the program's main thread.