|
View:
New views
4 Messages
—
Rating Filter:
Alert me
|
|
|
Force single evaluation?Hello, I call a C function from a Haskell program. I am using unsafePerformIO to use it outside a monad. Even though the C function does not have any side effect, I absolutely don't want to evaluate it more than once for performance reasons. But my impression is that it is evaluated several times. 1. Can I monitor somehow how often it is evaluated? 2. Can I ensure that the function is evaluated only once? I am using ghc 6.4.1 I ma grateful for any hint! Regards, Axel -- Phone: +46 8 790 4124, Email: axel@..., Web: www.it.kth.se/~axel -- --- Phone: +46 8 790 4124, Email: axel@..., Web: www.imit.kth.se/~axel _______________________________________________ FFI mailing list FFI@... http://www.haskell.org/mailman/listinfo/ffi |
|
|
Re: Force single evaluation?"Axel Jantsch" <axel@...> wrote:
> I call a C function from a Haskell program. I am using unsafePerformIO > to use it outside a monad. > > Even though the C function does not have any side effect, I absolutely > don't want to evaluate it more than once for performance reasons. But > my impression is that it is evaluated several times. > > 1. Can I monitor somehow how often it is evaluated? You could wrap it (in C) with another function that keeps a counter of invocations in a static local variable. result_t originalFn (arg1_t arg1, arg2_t arg2); result_t wrappedFn (arg1_t arg1, arg2_t arg2) { static int i = 0; i++; fprintf(stderr,"originalFn called %d times\n",i); return originalFn(arg1,arg2); } > 2. Can I ensure that the function is evaluated only once? How about stating in the type of the FFI decl that the C function is pure (even if it is not)? Then be sure to bind its result in only one place. That should guarantee it is called only once. foreign import ccall originalFn :: Arg1T -> Arg2T -> IO ResultT becomes foreign import ccall originalFn :: Arg1T -> Arg2T -> ResultT Regards, Malcolm _______________________________________________ FFI mailing list FFI@... http://www.haskell.org/mailman/listinfo/ffi |
|
|
Re: Force single evaluation?I tried both alternatives: foreign import ccall originalFn :: Arg1T -> Arg2T -> IO ResultT foreign import ccall originalFn :: Arg1T -> Arg2T -> ResultT but in both cases the C function originalFn is called several times for the same arguments. And it is bound only in one place. I don't understand why. Maybe the problem is that the data marshaling has to be done within the monad? My simplified codes is as follows: f :: InparT -> IO CInt f inPar = do inP <- malloc poke inP inPar r <- cfun inP free inP return r foreign import ccall "cfun" :: Ptr InparT -> IO CInt So even if I make cfun pure (which it is), the enclosing function f is not. Shall I pretend f is pure and wrap it into unsafePerformIO? Regards, Axel Malcolm Wallace <Malcolm.Wallace@...> wrote: > "Axel Jantsch" <axel@...> wrote: > > > I call a C function from a Haskell program. I am using unsafePerformIO > > to use it outside a monad. > > > > Even though the C function does not have any side effect, I absolutely > > don't want to evaluate it more than once for performance reasons. But > > my impression is that it is evaluated several times. > > > > 1. Can I monitor somehow how often it is evaluated? > > You could wrap it (in C) with another function that keeps a counter of > invocations in a static local variable. > > result_t originalFn (arg1_t arg1, arg2_t arg2); > result_t wrappedFn (arg1_t arg1, arg2_t arg2) { > static int i = 0; > i++; > fprintf(stderr,"originalFn called %d times\n",i); > return originalFn(arg1,arg2); > } > > > 2. Can I ensure that the function is evaluated only once? > > How about stating in the type of the FFI decl that the C function is > pure (even if it is not)? Then be sure to bind its result in only one > place. That should guarantee it is called only once. > > foreign import ccall originalFn :: Arg1T -> Arg2T -> IO ResultT > becomes > foreign import ccall originalFn :: Arg1T -> Arg2T -> ResultT > > Regards, > Malcolm > _______________________________________________ > FFI mailing list > FFI@... > http://www.haskell.org/mailman/listinfo/ffi > -- Phone: +46 8 790 4124, Email: axel@..., Web: www.it.kth.se/~axel _______________________________________________ FFI mailing list FFI@... http://www.haskell.org/mailman/listinfo/ffi |
|
|
Re: Force single evaluation?Am Mittwoch, 20. Dezember 2006 16:10 schrieb Axel Jantsch:
> [...] My simplified codes is as follows: > > f :: InparT -> IO CInt > f inPar = do > inP <- malloc > poke inP inPar > > r <- cfun inP > > free inP > return r This can be simplified to 'flip with cFun' (malloc/free pair => alloca, alloca/poke => with). > [...] So even if I make cfun pure (which it is), the enclosing function f is > not. This depends on the viewpoint: Unless malloc fails, f will return the same value for the same argument, so it can be considered pure. > Shall I pretend f is pure and wrap it into unsafePerformIO? You can do this, but you still depend on the compiler/interpreter not doing any funny transformations which could duplicate an application of f. I don't think that this will be a problem in practice, but to be on the safe side you could memoize f or cFun and perhaps even a 1-element cache might be enough to avoid all this trickery. Cheers, S. _______________________________________________ FFI mailing list FFI@... http://www.haskell.org/mailman/listinfo/ffi |
| Free Forum Powered by Nabble | Forum Help |