diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,8 +3,7 @@
 
 ## Usage
 
-The following will print the 10 most used words *and* output a bar graph
-showing the distribution of those 10 words.
+The following will print the 10 most used words.
 
 ```bash
  $ wordchoice test/ulysses.txt -n10 -o distribution.html
@@ -20,6 +19,13 @@
  2391: with
 ```
 
+To print the 10 most used words *and* write a bar graph:
+
+```bash
+ $ wordchoice test/ulysses.txt -n10 -o distribution.html
+```
+
+
 ## Installation
 
 ### Manual
@@ -33,7 +39,7 @@
 Install [nix](https://nixos.org/nix/), then type:
 
 ```bash
-nix-env -i
+nix-env -i wordchoice
 ```
 
 to download the package for Mac or Linux.
@@ -51,16 +57,4 @@
 
 ### Build
 
-To build this repo, simply type:
-
-```bash
- $ stack install
-```
-
-or
-
-```bash
- $ cabal new-build
-```
-
-in the `wordchoice/` directory.
+This repo should build with cabal, stack, and nix-build.
diff --git a/bench/Bench.hs b/bench/Bench.hs
new file mode 100644
--- /dev/null
+++ b/bench/Bench.hs
@@ -0,0 +1,12 @@
+module Main where
+
+import Criterion.Main
+import Data.Text.WordCount
+
+main = do
+    defaultMain [ env setupEnv $ \file ->
+                  bgroup "ulysses all"
+                      [ bench "226" $ whnf (fun 10000000) file ] ]
+    where fun      = topN
+          setupEnv = processFile "test/ulysses.txt"
+
diff --git a/default.nix b/default.nix
--- a/default.nix
+++ b/default.nix
@@ -14,5 +14,6 @@
   executableHaskellDepends = [ base ];
   testHaskellDepends = [ base ];
   homepage = "https://github.com/githubuser/wordchoice#readme";
+  description = "Get word counts and distributions";
   license = stdenv.lib.licenses.bsd3;
 }
diff --git a/src/Data/Text/WordCount.hs b/src/Data/Text/WordCount.hs
--- a/src/Data/Text/WordCount.hs
+++ b/src/Data/Text/WordCount.hs
@@ -6,6 +6,8 @@
     -- * For making graphs
     , makeFile
     , makeDistribution
+    -- * File processing with pandoc
+    , processFile
     -- * Low level-ish
     , buildFreq
     ) where
@@ -13,7 +15,7 @@
 import qualified Data.Map.Lazy as M
 import Data.Map.Lens
 import Control.Lens hiding (argument)
-import qualified Data.Text.Lazy as TL
+import qualified Data.Text as TL -- .Lazy as TL
 import Data.Tuple
 import Data.Monoid
 import Data.List
@@ -21,6 +23,7 @@
 import Graphics.Rendering.Chart.Easy hiding (argument)
 import Graphics.Rendering.Chart.Backend.Diagrams
 import Data.Char
+import Data.Text.WordCount.FileRead
 
 -- | Return top n words and their frequencies
 --
@@ -66,5 +69,5 @@
     layout_y_axis . laxis_override .= axisGridHide
     layout_left_axis_visibility . axis_show_ticks .= False
     plot $ fmap plotBars $ liftEC $ do
-        plot_bars_values .= [ (x,[y]) | (x,y) <- values ]
-        plot_bars_item_styles .= [ (fillStyle, Nothing) ]
+        plot_bars_values .= fmap (over _2 pure) values
+        plot_bars_item_styles .= pure (fillStyle, Nothing)
diff --git a/src/Data/Text/WordCount/Exec.hs b/src/Data/Text/WordCount/Exec.hs
--- a/src/Data/Text/WordCount/Exec.hs
+++ b/src/Data/Text/WordCount/Exec.hs
@@ -1,7 +1,7 @@
 module Data.Text.WordCount.Exec where
     
 import Data.Monoid
-import qualified Data.Text.Lazy.IO as TLIO
+import qualified Data.Text.IO as TLIO -- .Lazy.IO as TLIO
 import Paths_wordchoice
 import Options.Applicative
 import Data.Maybe
diff --git a/src/Data/Text/WordCount/FileRead.hs b/src/Data/Text/WordCount/FileRead.hs
--- a/src/Data/Text/WordCount/FileRead.hs
+++ b/src/Data/Text/WordCount/FileRead.hs
@@ -3,26 +3,29 @@
 
 import Text.Pandoc
 import Filesystem.Path.CurrentOS as F
-import qualified Data.Text.Lazy as TL
-import qualified Data.Text.Lazy.IO as TLIO
+import qualified Data.Text as T
+import qualified Data.Text.IO as TIO
 import qualified Data.ByteString.Lazy as BSL
 
 eitherError = either (error . show) id
 
 -- | Process a file given its filename. Return text only, discarding superflouous material.
-processFile :: String -> IO TL.Text
-processFile filepath = case (extension . decodeString $ filepath) of
-    (Just "md") -> TL.pack . writePlain def . filterCode . eitherError . readMarkdown def . TL.unpack <$> TLIO.readFile filepath
-    (Just "dbk") -> TL.pack . writePlain def . filterCode . eitherError . readDocBook def . TL.unpack <$> TLIO.readFile filepath
-    (Just "docx") -> TL.pack . writePlain def . filterCode . fst . eitherError . readDocx def <$> BSL.readFile filepath
-    (Just "epub") -> TL.pack . writePlain def . filterCode . fst . eitherError . readEPUB def <$> BSL.readFile filepath
-    (Just "html") -> TL.pack . writePlain def . filterCode . eitherError . readHtml def . TL.unpack <$> TLIO.readFile filepath
-    (Just "tex") -> TL.pack . writePlain def . filterCode . eitherError . readLaTeX def . TL.unpack <$> TLIO.readFile filepath
-    (Just "xml") -> TL.pack . writePlain def . filterCode . eitherError . readOPML def . TL.unpack <$> TLIO.readFile filepath
-    (Just "odt") -> TL.pack . writePlain def . filterCode . fst . eitherError . readOdt def <$> BSL.readFile filepath
-    (Just "rst") -> TL.pack . writePlain def . filterCode . eitherError . readRST def . TL.unpack <$> TLIO.readFile filepath
-    (Just "textile") -> TL.pack . writePlain def . filterCode . eitherError . readTextile def . TL.unpack <$> TLIO.readFile filepath
-    _ -> TLIO.readFile filepath
+processFile :: String -> IO T.Text
+processFile filepath = T.filter goodChar <$> case (extension . decodeString $ filepath) of
+    (Just "md") -> T.pack . writePlain def . filterCode . eitherError . readMarkdown def . T.unpack <$> TIO.readFile filepath
+    (Just "dbk") -> T.pack . writePlain def . filterCode . eitherError . readDocBook def . T.unpack <$> TIO.readFile filepath
+    (Just "docx") -> T.pack . writePlain def . filterCode . fst . eitherError . readDocx def <$> BSL.readFile filepath
+    (Just "epub") -> T.pack . writePlain def . filterCode . fst . eitherError . readEPUB def <$> BSL.readFile filepath
+    (Just "html") -> T.pack . writePlain def . filterCode . eitherError . readHtml def . T.unpack <$> TIO.readFile filepath
+    (Just "tex") -> T.pack . writePlain def . filterCode . eitherError . readLaTeX def . T.unpack <$> TIO.readFile filepath
+    (Just "xml") -> T.pack . writePlain def . filterCode . eitherError . readOPML def . T.unpack <$> TIO.readFile filepath
+    (Just "odt") -> T.pack . writePlain def . filterCode . fst . eitherError . readOdt def <$> BSL.readFile filepath
+    (Just "rst") -> T.pack . writePlain def . filterCode . eitherError . readRST def . T.unpack <$> TIO.readFile filepath
+    (Just "textile") -> T.pack . writePlain def . filterCode . eitherError . readTextile def . T.unpack <$> TIO.readFile filepath
+    _ -> TIO.readFile filepath
+
+goodChar :: Char -> Bool
+goodChar = not . flip any (".,?_()![]{}*&$#" :: String) . (==)
 
 -- | Filter out code and tables from the document
 filterCode :: Pandoc -> Pandoc
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,66 +1,6 @@
-# This file was automatically generated by 'stack init'
-#
-# Some commonly used options have been documented as comments in this file.
-# For advanced use and comprehensive documentation of the format, please see:
-# http://docs.haskellstack.org/en/stable/yaml_configuration/
-
-# Resolver to choose a 'specific' stackage snapshot or a compiler version.
-# A snapshot resolver dictates the compiler version and the set of packages
-# to be used for project dependencies. For example:
-#
-# resolver: lts-3.5
-# resolver: nightly-2015-09-21
-# resolver: ghc-7.10.2
-# resolver: ghcjs-0.1.0_ghc-7.10.2
-# resolver:
-#  name: custom-snapshot
-#  location: "./custom-snapshot.yaml"
 resolver: lts-8.12
-
-# User packages to be built.
-# Various formats can be used as shown in the example below.
-#
-# packages:
-# - some-directory
-# - https://example.com/foo/bar/baz-0.0.2.tar.gz
-# - location:
-#    git: https://github.com/commercialhaskell/stack.git
-#    commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
-# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
-#   extra-dep: true
-#  subdirs:
-#  - auto-update
-#  - wai
-#
-# A package marked 'extra-dep: true' will only be built if demanded by a
-# non-dependency (i.e. a user package), and its test suites and benchmarks
-# will not be run. This is useful for tweaking upstream packages.
 packages:
 - '.'
-# Dependency packages to be pulled from upstream that are not in the resolver
-# (e.g., acme-missiles-0.3)
 extra-deps: []
-
-# Override default flag values for local packages and extra-deps
 flags: {}
-
-# Extra package databases containing global packages
 extra-package-dbs: []
-
-# Control whether we use the GHC we find on the path
-# system-ghc: true
-#
-# Require a specific version of stack, using version ranges
-# require-stack-version: -any # Default
-# require-stack-version: ">=1.4"
-#
-# Override the architecture used by stack, especially useful on Windows
-# arch: i386
-# arch: x86_64
-#
-# Extra directories used by stack for building
-# extra-include-dirs: [/path/to/dir]
-# extra-lib-dirs: [/path/to/dir]
-#
-# Allow a newer minor version of GHC than the snapshot specifies
-# compiler-check: newer-minor
diff --git a/wordchoice.cabal b/wordchoice.cabal
--- a/wordchoice.cabal
+++ b/wordchoice.cabal
@@ -1,5 +1,5 @@
 name:                wordchoice
-version:             0.1.0.0
+version:             0.1.0.1
 synopsis:            Get word counts and distributions
 description:         A command line tool to compute the word distribution from various types of document, converting to text with pandoc.
 homepage:            https://github.com/githubuser/wordchoice#readme
@@ -35,7 +35,7 @@
   default-language:    Haskell2010
   default-extensions:  OverloadedStrings
 
-executable wordchoice
+executable wrd
   hs-source-dirs:      app
   main-is:             Main.hs
   ghc-options:         -threaded -rtsopts -with-rtsopts=-N
@@ -51,6 +51,19 @@
                      , wordchoice
   ghc-options:         -threaded -rtsopts -with-rtsopts=-N
   default-language:    Haskell2010
+
+benchmark wordchoice-bench
+  type:             exitcode-stdio-1.0
+  hs-source-dirs:   bench
+  main-is:          Bench.hs
+  build-depends:    base
+                  , criterion
+                  , wordchoice
+  if flag(llvm-fast)
+    ghc-options:       -threaded -rtsopts -with-rtsopts=-N -fllvm -optlo-O3 -O3
+  else
+    ghc-options:       -threaded -rtsopts -with-rtsopts=-N -O3
+  default-language: Haskell2010
 
 source-repository head
   type:     git
