Working character by character in Haskell
I'm trying to create a fast program in Haskell that reads the content of a file, do some stuff with its characters (one by one) an then save the final result (the modified characters) in another file. The fastest program I've developed so far is: main :: IO () main = do bmFile <- openFileEx "in.txt" (BinaryMode ReadMode) bmString <- hGetContents bmFile str <- copyFile bmString [] writeFile "out.txt" str hClose bmFile copyFile :: String -> String -> IO String copyFile [] s = return (reverse s) copyFile (a:as) s = copyFile as ( (doSomeStuffWith a):s) What I can't understand is why a similar program, written in C, is much faster than the Haskell program. Here you have the C program: void main() { FILE *in, *out; char ch; in = fopen("in.txt","rb"); out = fopen("out.txt","wb"); while ( (ch=getc(in)) != EOF) putc(doSomeStuffWith(ch),out); fclose(out); fclose(in); } For example, suppose function doSomeStuffWith returns its own parameter. Using a 1.5MB file in this case, the Haskell program ends in almost 5 seconds, while the C program ends in less than 0.5 seconds... Is my Haskell program too bad implemented? (I'm using GHC 4.08-1 under a Windows 98 platform.) Thanks, -- Andre
Andre W B Furtado writes: : | copyFile :: String -> String -> IO String | copyFile [] s = return (reverse s) | copyFile (a:as) s = copyFile as ( (doSomeStuffWith a):s) : | For example, suppose function doSomeStuffWith returns its own | parameter. Using a 1.5MB file in this case, the Haskell program | ends in almost 5 seconds, while the C program ends in less than 0.5 | seconds... Is my Haskell program too bad implemented? (I'm using | GHC 4.08-1 under a Windows 98 platform.) You've used an accumulating parameter (s) and then reversed it once you reach the end of the input. The time cost for this is still O(n) where n is the length of the input, but the space cost is O(n) in your Haskell program and O(1) in your C program, so perhaps the Haskell version's having to spend time enlarging its heap? Here's an O(n) time, O(1) space version of copyFile: copyFile = return . map doSomeStuffWith
participants (2)
-
Andre W B Furtado -
Tom Pledger