Add some more profiling machinery

In particular some key functions are now decorated for use with
either [line_profiler] or [memory_profiler]:

To get a line-by-line profile, run:

    kernprof.py -l <script.py>

To get a memory profile, run:

    mprof run --python <script.py>

[line_profiler]: https://pythonhosted.org/line_profiler/
[memory_profiler]: https://github.com/fabianp/memory_profiler