Haskell: как быстрее всего передать данные от дескриптора к дескриптору?

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

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

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


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


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

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


person Cetin Sert    schedule 27.02.2012    source источник


Ответы (2)


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

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

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

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

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

person Thomas M. DuBuisson    schedule 27.02.2012
comment
Если у вас нет времени, просто сделайте один и не беспокойтесь о производительности, если это не проблема. ^_^ Я думаю, что оба будут значительно быстрее, чем то, что я мог бы придумать самостоятельно. Это первый раз, когда я вижу, что кто-то явно думает о чьих-то временных ограничениях! - person Cetin Sert; 27.02.2012
comment
где живет почти Форевер? Гугл утверждает, что не может его найти. - person ben w; 27.02.2012
comment
@benw, когда Hoogle не может его найти, попробуйте Hayoo. Однако в этом случае Hayoo также не может найти almostForever. ›,‹ - person Dan Burton; 27.02.2012
comment
+1 Лично я считаю ленивый hGetContents очень элегантным и интуитивно понятным решением. - person Dan Burton; 27.02.2012
comment
@benw almostForever был просто моей выдуманной функцией, чтобы подразумевать, что конструкция цикла зависит от спрашивающего, вероятно, будет длиться более одного цикла, а не навсегда. Например, вычисление ackerman 10 10. - person Thomas M. DuBuisson; 27.02.2012

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

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

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

almostForever $ Data.ByteString.hGetSome h1 nr >>= Data.ByteString.hPutStr h2
person dflemstr    schedule 27.02.2012