Personal tools

Performance/FFI

From HaskellWiki

< Performance(Difference between revisions)
Jump to: navigation, search
(+cat)
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[Category:Performance:FFI]]
+
{{Performance infobox}}
= Improving performance for FFI code =
+
[[Category:Performance|FFI]]
  +
== Improving performance for FFI code ==
   
== Use "unsafe" foreign imports ==
+
=== Use "unsafe" foreign imports ===
   
 
If you annotate a foreign import declaration with the <tt>unsafe</tt> keyword, this indicates to the compiler that (1) the call will not invoke another Haskell function, directly or indirectly, and (2) you don't mind if any other running Haskell threads in the system are blocked for the duration of the call.
 
If you annotate a foreign import declaration with the <tt>unsafe</tt> keyword, this indicates to the compiler that (1) the call will not invoke another Haskell function, directly or indirectly, and (2) you don't mind if any other running Haskell threads in the system are blocked for the duration of the call.
   
 
These restrictions enable the compiler to generate a much more efficient call. In particular, GHC will generate a simple inline function call for an <tt>unsafe</tt> call, but a <tt>safe</tt> call by contrast is quite heavyweight: it involves saving some state on the Haskell stack, and a couple of calls into the runtime are made in addition to the foreign call itself.
 
These restrictions enable the compiler to generate a much more efficient call. In particular, GHC will generate a simple inline function call for an <tt>unsafe</tt> call, but a <tt>safe</tt> call by contrast is quite heavyweight: it involves saving some state on the Haskell stack, and a couple of calls into the runtime are made in addition to the foreign call itself.
  +
  +
=== Take care when marshalling ===
  +
  +
One big performance eater can be marshalling from foreign code to local code. Try to do as little of it as possible, that is, try to keep your data on one side of the FFI. If you do need to marshal data across the FFI, do it in large chunks; calling across the FFI to generate datastructures is much more expensive than building appropriate structures in Haskell and then handing those off in one go.

Latest revision as of 15:31, 5 April 2007

Haskell Performance Resource

Constructs:
Data Types - Functions
Overloading - FFI - Arrays
Strings - Integers - I/O
Floating point - Concurrency
Modules - Monads

Techniques:
Strictness - Laziness
Avoiding space leaks
Accumulating parameter

Implementation-Specific:
GHC - nhc98 - Hugs
Yhc - JHC

[edit] 1 Improving performance for FFI code

[edit] 1.1 Use "unsafe" foreign imports

If you annotate a foreign import declaration with the unsafe keyword, this indicates to the compiler that (1) the call will not invoke another Haskell function, directly or indirectly, and (2) you don't mind if any other running Haskell threads in the system are blocked for the duration of the call.

These restrictions enable the compiler to generate a much more efficient call. In particular, GHC will generate a simple inline function call for an unsafe call, but a safe call by contrast is quite heavyweight: it involves saving some state on the Haskell stack, and a couple of calls into the runtime are made in addition to the foreign call itself.

[edit] 1.2 Take care when marshalling

One big performance eater can be marshalling from foreign code to local code. Try to do as little of it as possible, that is, try to keep your data on one side of the FFI. If you do need to marshal data across the FFI, do it in large chunks; calling across the FFI to generate datastructures is much more expensive than building appropriate structures in Haskell and then handing those off in one go.