Question: Recently me and my friends were benchmarking different programming languages. As I'm learning Haskell lately, I wanted to show that a functional language will perform nearly as good as C with simpler code. But the code I pasted below, compiled with GHC's -O3 option, was executing about 1.6 s on my machine. Equivalent scripts in Python and Ruby executed faster (it was a simple for loop).

```
import System.IO

saveLine fh x = hPutStrLn fh $ show x ++ "\t" ++ show (x^2)

main = do
    fh <- openFile "haskell.txt" WriteMode
    mapM (saveLine fh) [1..999999]
    hClose fh

```

You can check out [codes in other languages here](http://pastebin.com/7T5hpXCq) (I wrote only the ones in Python and Ruby).

The question is - how to make it run faster?

Answer: 
First off, benchmarks where you perform some simple calculation and write each result to a file are *only useful to test the IO system*. They say nothing at all about computation efficiency, because most of the time is spent with file accesses. If you want to compare how fast languages are for calculating things, you need to do something processor-intensive (e.g. summing all those square values) and then output only that single result.

If you actually want to compare file-output performance, the main problem in Haskell is its `String` type. It's a simple list of characters, handy for doing simple text manipulations by hand but with ridiculous overhead for standard tasks. For faster performance, use [bytestrings](http://hackage.haskell.org/package/bytestring) or [`Text`](http://hackage.haskell.org/package/text). Specifically, you need a faster alternative to `show`. Check out the [text-format package](http://hackage.haskell.org/package/text-format).
The problems are: 1) using `String`, and 2) the formatting of integer values to character data (either `ByteString` or `String`).

```
{-# LANGUAGE OverloadedStrings #-}

import System.IO
import qualified Data.ByteString.Char8 as BS

-- saveLine fh x = hPutStrLn fh $ show x ++ "\t" ++ show (x^2) -- original version
-- saveLine fh x = hPutStrLn fh "123456\t123456789012" -- String version
saveLine fh x = BS.hPutStrLn fh "123456\t123456789012" -- ByteString version

main = do
    fh <- openFile "haskell.txt" WriteMode
    mapM_ (saveLine fh) [1..999999]
    hClose fh

```

The run times on my machine are (GHC 7.8.3):

```
original version:   1.6 secs
String version:     0.7 secs
ByteString version: 0.3 secs

```

Thus, the run time can be significantly improved if one can find a faster way to format integer values to ByteStrings.