如果我想调用多个C函数,每个函数都依赖于前一个函数的结果,那么创建一个包装器C函数来处理这三个调用是否更好?与使用Haskell FFI而不转换类型相比,它会花费相同的代价吗?
假设我有以下Haskell代码:
foo :: CInt -> IO CInt
foo x = do
a <- cfA x
b <- cfB a
c <- cfC c
return c
每个函数cf*
都是一个C调用。
从性能的角度来看,创建一个单独的C函数如cfABC
,然后在Haskell中只进行一次外部调用会更好吗?
int cfABC(int x) {
int a, b, c;
a = cfA(x);
b = cfB(a);
c = cfC(b);
return c;
}
Haskell 代码:
foo :: CInt -> IO CInt
foo x = do
c <- cfABC x
return c
如何测量从Haskell调用C的性能开销?不是C函数本身的开销,而是从Haskell到C再返回时所产生的“上下文切换”的开销。
foreign ccall unsafe
(其中unsafe
是关键)基本上和内联C函数调用一样便宜。 然而,在使用unsafe
时必须非常小心,而安全变体(foreign ccall
)成本更高并涉及锁定。 - gsprdouble x
,返回sin(x)*sin(x)*cos(x)/2.0
。我使用GCC 4.7.2和-O2编译它。基准测试将其用100000000个不同的参数从0到pi / 2调用,并汇总结果。使用“foreign ccall”大约需要9.6秒,而使用“foreign ccall unsafe”需要4.6秒。从实际的C程序中调用它所需的运行时间为4.4-4.5秒。这至少可以让你有一个想法。Haskell代码是使用GHC 7.4.2编译的。 - gspr