JSON encoder improvements

We should be using a tuple instead of a list to save a little bit of memory.
I added an optional LRU cache to the JSON encoder that is supported from Python 3.3 or can use the functools backport. Since the encoder is idempotent there is no reason to calculate the same return result again. I was very conservative with what should be cached. QuerySets and Promises are not cached and dicts are not cached because they are not hashable. I have no idea about numpy so I just left it as it is.
I'm not familiar with YAML but I believe that the same approach can be applied.
Documentation should be added if the second commit is mergable in your opinion.
The first commit should definetly be cherrypicked if we decide not to introduce an LRU cache for encoders.