Haskell FFI 内存分配性能问题

5
我正在使用FFI到C来发送中大型数据(约100MB)到C程序,只是一些字符串列表。然而,我使用的所有方法似乎需要不合理的时间(约10秒)。经过分析,发现实际的内存分配需要时间。我尝试过以下几种方式:
- 作为常规字符串发送(`newCString`) - 转换为ByteStrings(`unsafeUseAsCString`) - 转换为字符向量(`unsafeWith >>= withForeignPtr ...`)
什么是跨C FFI发送数据的最快方法?

4
这些字符串有多长?有多少个?你能否提供一个简单的示例来重现这个问题? - Bakuriu
2
你的数据最初是如何表示的? - Reid Barton
这是一个具有5个字段的标准类型,我正在将其转换为字符串以便在C中传递给数据库客户端。我还尝试过使用mallocBytes一次性分配所有内容,但速度似乎同样慢。另一个数据点是,GHC的分析表明,对于这个大约100MB的数据集,大约分配了15GB的内存。 - ooblahman
也尝试过使用 newCString 进行标准的 marshalling(如上所示),以及使用 Data.Vector.Storable 存储可存储字符的列表。 - ooblahman
2
很难在没有代码的情况下给出关于你应该做什么的建议,但有一件事是肯定不应该做的,那就是处理100MB的字符串,这将至少占用4GB的堆分配空间。 - Reid Barton
2个回答

0

你可能需要创建一个自定义数据类型,使用使用newAlignedPinnedByteArray分配的MutableByteArray,并将其转换为可以通过mutableByteArrayContents传递给C的内容。

另一种选择是,如果你可以重写与之交互的C API,就可以给C函数一个FunPtr,它会一次传递一个合理大小的Haskell数据块。


0
正如Reid Barton在评论中所说,如果你有100MB的字符串,无论你怎么处理它,你的分配都会非常糟糕。
你的减速不是来自FFI,而是因为一开始就有100MB的字符串。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接