2015-09-16 24 views
5

Ich verwende ein FFI zu C, um mittelgroße Datenmengen (~ 100 MB) an ein C-Programm zu senden - nur eine Liste von Zeichenfolgen. Jedoch scheinen alle Methoden, die ich verwendet habe, unangemessen lange Zeit zu benötigen (~ 10 Sekunden). Beim Profiling scheint es sich um die tatsächliche Speicherzuweisung zu handeln, die Zeit braucht. Ich habe versucht:Haskell FFI Speicherzuweisung Leistungsproblem

  • Senden als reguläre Strings (newCString)
  • Umwandlung in ByteStrings (unsafeUseAsCString)
  • Umwandlung in Vektor von Zeichen (unsafeWith >>= withForeignPtr ...)

Was ist der schnellste Weg, Daten über einen C FFI senden?

+4

Wie lang sind diese Zeichenfolgen? Wie viele davon? Können Sie uns nicht ein kleines Beispiel geben, das das Problem reproduziert? – Bakuriu

+2

Wie werden Ihre Daten dargestellt? –

+0

Es ist ein Standardtyp mit 5 Feldern, und ich konvertiere zu/von Strings, um an einen Datenbankclient in C zu übergeben. Ich habe zusätzlich versucht, alles auf einmal mit mallocBytes zuzuteilen und es scheint genauso langsam zu sein. Ein weiterer Datenpunkt ist, dass die GHC-Profilerstellung ergab, dass ~ 15 GB für diese ~ 100 MB-Datenmenge zugewiesen wurden. – ooblahman

Antwort

0

Wie Reid Barton in Kommentaren sagte, wenn Sie 100MB Strings haben, wird Ihre Zuweisung schrecklich sein, egal was Sie damit anfangen.

Ihre Verlangsamung ist nicht von der FFI, es von 100MB Strings zu beginnen.

0

Sie müssen wahrscheinlich einen benutzerdefinierten Datentyp erstellen, indem Sie MutableByteArray zugewiesen mit newAlignedPinnedByteArray verwenden und in etwas verwandelt werden, das an C mit mutableByteArrayContents übergeben werden kann. Wenn Sie die C API, mit der Sie arbeiten, neu schreiben können, geben Sie der C-Funktion FunPtr eine Alternative, die einen Teil der Haskell-Daten, mit denen Sie gerade arbeiten, in einem vernünftigen Umfang übergibt.