2015-09-16 14 views
5

Używam FFI do C, aby przesłać średnio duże ilości danych (~ 100 MB) do programu w języku C - wystarczy lista ciągów. Jednak wszystkie metody, których użyłem, wydają się zajmować nieuzasadnioną ilość czasu (~ 10 sekund). Podczas profilowania wygląda na faktyczną alokację pamięci, która wymaga czasu. Próbowałem:Wydajność przydzielania pamięci Haskell FFI Wydajność

  • wysyłania jak zwykłe ciągi (newCString)
  • konwersję do ByteStrings (unsafeUseAsCString)
  • konwersję do wektora znaków (unsafeWith >>= withForeignPtr ...)

Co to najszybszy sposób, aby wysyłać dane przez C FFI?

+4

Jak długo są te struny? Ilu z nich? Nie jesteś w stanie podać małego przykładu, który odtwarza problem? – Bakuriu

+2

W jaki sposób reprezentowane są twoje dane? –

+0

Jest to standardowy typ z 5 polami i konwertuję do/z ciągów, aby przekazać do klienta bazy danych w C. Próbowałem również przydzielić wszystkie naraz za pomocą mallocBytes i wydaje się, że jest tak samo powolny. Innym punktem danych jest to, że profilowanie GHC wskazało, że ~ 15 GB zostało przydzielonych dla tego zbioru danych ~ 100MB. – ooblahman

Odpowiedz

0

Jak powiedział Reid Barton w komentarzach, jeśli masz 100 MB ciągów, twoje przydzielenie będzie okropne, bez względu na to, co z nim zrobisz.

Twoje spowolnienie nie pochodzi z FFI, ponieważ ma 100 MB ciągów na początek.

0

Najprawdopodobniej będziesz musiał utworzyć niestandardowy typ danych, korzystając z MutableByteArray przydzielonego z newAlignedPinnedByteArray i przekształcić go w coś, co można przekazać do C z mutableByteArrayContents.

Alternatywą, jeśli możesz przerobić interfejs API C, z którym się łączysz, jest nadanie funkcji C wartości FunPtr, która przekazuje mu rozsądnie wielkości fragment danych Haskella, z którymi pracujesz jednocześnie.