2015-01-26 6 views
4

"Real World Haskell"(ch. 7, 189 페이지)에서 IO 버퍼링에 대해 읽고 버퍼링 크기가 성능에 어떤 영향을 미치는지 테스트하려고했습니다.버퍼링으로 Haskell IO를 빠르게하는 방법은 무엇입니까?

import System.IO 
import Data.Time.Clock 
import Data.Char(toUpper) 

main :: IO() 
main = do 
    hInp <- openFile "bigFile.txt" ReadMode 
    let bufferSize = truncate $ 2**10 
    hSetBuffering hInp (BlockBuffering (Just bufferSize)) 
    bufferMode <- hGetBuffering hInp 
    putStrLn $ "Current buffering mode: " ++ (show bufferMode) 

    startTime <- getCurrentTime 
    inp <- hGetContents hInp 
    writeFile "processed.txt" (map toUpper inp) 
    hClose hInp 
    finishTime <- getCurrentTime 
    print $ diffUTCTime finishTime startTime 
    return() 

가 그럼 난 다른 버퍼 크기와 더불어, "bigFile.txt"

-rw-rw-r-- 1 user user 96M янв. 26 09:49 bigFile.txt 

을 생성하고이 파일에 대해 내 프로그램을 실행

Current buffering mode: BlockBuffering (Just 32) 
9.744967s 

Current buffering mode: BlockBuffering (Just 1024) 
9.667924s          

Current buffering mode: BlockBuffering (Just 1048576) 
9.494807s  

Current buffering mode: BlockBuffering (Just 1073741824) 
9.792453s 

하지만 프로그램 실행 시간이 거의입니다 똑같다. 정상입니까, 아니면 제가 잘못하고 계시나요?

답변

11

최신 OS에서는 1) 커널이 미리 읽기를 수행하고 2) 파일이 이미 페이지 캐시에있을 수 있기 때문에 버퍼 크기가 파일을 선형 적으로 읽는 데 거의 영향을 미치지 않을 가능성이 있습니다 최근에 파일을 읽으십시오.

다음은 쓰기에 대한 버퍼링 효과를 측정하는 프로그램입니다. 일반적인 결과는 다음과 같습니다

$ ./mkbigfile 32  -- 12.864733s 
$ ./mkbigfile 64  -- 9.668272s 
$ ./mkbigfile 128  -- 6.993664s 
$ ./mkbigfile 512  -- 4.130989s 
$ ./mkbigfile 1024 -- 3.536652s 
$ ./mkbigfile 16384 -- 3.055403s 
$ ./mkbigfile 1000000 -- 3.004879s 

출처 :

{-# LANGUAGE OverloadedStrings #-} 

import qualified Data.ByteString as BS 
import Data.ByteString (ByteString) 
import Control.Monad 
import System.IO 
import System.Environment 
import Data.Time.Clock 

main = do 
    (arg:_) <- getArgs 
    let size = read arg 
    let bs = "abcdefghijklmnopqrstuvwxyz" 
     n = 96000000 `div` (length bs) 
    h <- openFile "bigFile.txt" WriteMode 
    hSetBuffering h (BlockBuffering (Just size)) 
    startTime <- getCurrentTime 
    replicateM_ n $ hPutStrLn h bs 
    hClose h 
    finishTime <- getCurrentTime 
    print $ diffUTCTime finishTime startTime 
    return() 
+0

그래서 왜 영업 이익은 자신의 프로그램에 차이의 종류를 보지 못했어요? –

+3

OP의 프로그램은 버퍼링을 쓰기 핸들이 아닌 읽기 핸들에 설정합니다. – ErikR

+0

댓글이 업데이트되었습니다. – ErikR