 
 import Foundation
 
+private struct MapHolder {
+    let type: Any.Type
+    let map: [String: Int]
+}
+private var typesIndexMap = [MapHolder]()
+
 /**
     A CerealDecoder handles decoding items that were encoded by a `CerealEncoder`.
 */
 public struct CerealDecoder {
 
-    private var items: [String: CoderTreeValue]
-
+    private var items: [CoderTreeValue]
+    private let reverseRange: StrideThrough<Int>
+    private let indexMap: [String: Int]?
+
+    private func itemForKey(key: String) -> CoderTreeValue? {
+        if items.count > 100 { // it appears that on small amount of items, a simmple array enumeration is faster than a dictionary lookup
+            if let index = indexMap?[key], case let .PairValue(_, value) = items[index] {
+                return value
+            }
+        }
+        for index in reverseRange {
+            guard case let .PairValue(keyValue, value) = items[index], case let .StringValue(itemKey) = keyValue else { continue }
+            if itemKey == key {
+                return value
+            }
+        }
+        return nil
+    }
     /**
     Initializes a `CerealDecoder` with the data contained in data.
     

     - returns:      The instantiated object, or nil if no object was at the specified key.
     */
    public func decode<DecodedType: protocol<RawRepresentable, CerealRepresentable> where DecodedType.RawValue: CerealRepresentable>(key: String) throws -> [DecodedType]? {
        guard let data = items[key] else {
            return nil
        }


     - returns:      The instantiated object, or nil if no object was at the specified key.
     */
    public func decode<DecodedKeyType: protocol<RawRepresentable, CerealRepresentable, Hashable>, DecodedValueType: CerealRepresentable where DecodedKeyType.RawValue: CerealRepresentable>(key: String) throws -> [[DecodedKeyType: DecodedValueType]]? {
        guard let data = self.itemForKey(key), case let .ArrayValue(items) = data else {
            return nil
        }

