
On Sat, Apr 14, 2007 at 07:58:25PM +0400, Sergey Perminov wrote:
I wish to optimize Haskell code using ByteString, direct reading Doubles form it, direct writing Doubles to it.
I've tried Don Stewart's code http://hpaste.org/26 that uses calling to C functions to implement necessary readDouble & showDouble.
readDouble works ok. showDouble always return "nan" in Mac OS X (but works well in Windows). I'm using GHC 6.6 in Mac (http://www.haskell.org/ghc/download_ghc_66.html#macosxppc) and in Windows (http://www.haskell.org/ghc/download_ghc_66.html#windows).
I've made showInt based on showDouble: http://hpaste.org/1390 It works well in Mac OS X. It seems that problem happens only when I send CDouble (or CLDouble) to C function.
My conf: PowerBook G4, Mac OS X 10.4.9, powerpc-apple-darwin8-gcc-4.0.1
foreign import ccall unsafe "static stdio.h snprintf" c_printf_double :: Ptr CChar -> CSize -> Ptr CChar -> CInt -> IO CInt is illegal (and slow). snprintf is a varargs function, and varargs functions are allowed to use a completely different calling convention from non-varargs functions. I'm pretty sure the FFI allows nasal demons for what you just did, using a non-varargs call for a varargs function... In any case the fundamental issue is i386 vs. ppc. i386 has so few registers that everything is passed on the stack, and the ordinary convention supports varargs too. ppc normally puts things in registers, but does different stuff for varargs. There is no way to use varargs functions from the FFI. Also, snprintf is an INTERPRETER - you won't gain much if every time you need to print a double you do a dynamic dispatch on the format string! If you care about performance enough to be using the FFI at all, you probably ought to hand-code the printer, not call snprintf. Stefan