Haskell: какой самый быстрый способ передачи данных от дескриптора к дескриптору? - PullRequest
1 голос
/ 27 февраля 2012

Как я могу определить

pipe :: Handle -> Handle -> IO ()

наиболее эффективным способом в Haskell (платформа 2011-04 или ghc 7.4)?


Обновление 1 : Как написать прокси с минимальными накладными расходами для localhost: 3389 в Haskell?


Обновление 2 : Использование системного вызова GNU / Linux `splice` для передачи данных Socket to Socket в Haskell

использует системный вызов GNU / Linux splice для передачи данных без копирования между двумя сетевыми сокетами, а также освобождает место для переносимого сокета-to-socket splice заменитель, написанный на Haskell, который использует (mallocBytes, hGetBufSome и hPutBuf) одноразовый буфер пространства пользователя во всем цикле передачи данных, избегая крошечных выделений, которые приводят к нагрузке на мусорколлектор с повторными вызовами на recv, sendAll из пакета bytestring.

Ответы [ 2 ]

1 голос
/ 27 февраля 2012

Я предполагаю, что вы имеете дело с сокетами из-за ваших тегов.

В этом случае используйте пакет sendfile для выполнения операции с sendFile. Обратите внимание, что вы должны использовать сетевую библиотеку Haskell и реальные сокеты; он не работает с ручками.

Если вы имеете дело с абстрактными дескрипторами, вам нужно сделать то, что предложил @ thomas-m-dubuisson, и явно скопировать дескрипторы, потому что вам нужна некоторая буферизация, чтобы сделать операцию эффективной. Однако не следует использовать ленивые байтовые строки, потому что hGetSome не будет читать достаточно, чтобы сделать ленивые байтовые строки более эффективными.

almostForever $ Data.ByteString.hGetSome h1 nr >>= Data.ByteString.hPutStr h2
1 голос
/ 27 февраля 2012

Я не думаю, что вы найдете какое-либо решение без FFI, которое значительно превосходит либо:

almostForever $ Data.ByteString.hGetSome h1 nr >>= Data.ByteString.hPutStr h2

Или, возможно, вы немного выиграете, используя ленивые байтовые строки:

Data.ByteString.Lazy.hGetContents  h1 >>= Data.ByteString.Lazy.hPut h2

Если у вас есть время, запустите их.Если у вас нет времени, просто сделайте это и не беспокойтесь о производительности, если только это не является проблемой.

...