     /// `URLRequests` and the same processors. `URLRequests` are compared
     /// just by their `URLs`.
     public static func cacheKey(for request: Request) -> AnyHashable {
-        return request.cacheKey ?? AnyHashable(Key(request: request) {
+        return request.cacheKey ?? AnyHashable(makeCacheKey(request))
+    }
+    
+    private static func makeCacheKey(_ request: Request) -> Key {
+        return Key(request: request) {
             $0.container.urlString == $1.container.urlString && $0.processor == $1.processor
-        })
+        }
     }
 
     /// Returns a key which compares requests with regards to loading images.

            return ref
        }

        /// Memoized decompressor
        #if !os(macOS)
        private static let decompressor = AnyProcessor(Decompressor())
        #endif


    /// Custom info passed alongside the request.
    public var userInfo: Any?
    
    
    // MARK: Initializers
    
    public init(url: URL) {
        container = Container(resource: Resource.url(url))
        container.urlString = url.absoluteString
    }
    
    public init(urlRequest: URLRequest) {
        container = Container(resource: Resource.request(urlRequest))
        container.urlString = urlRequest.url?.absoluteString
    }

    
    // Everything in the scope below exists solely to improve performance

    fileprivate var container: Container

    private mutating func applyMutation(_ closure: (Container) -> Void) {
        if !isKnownUniquelyReferenced(&container) {
            container = container.copy()
        }
        closure(container)
    }

    /// `Request` stores its parameters in a `Container` to avoid memberwise
    /// retain/release when `Request` is passed around (and it is passed around
    /// **a lot**). This optimization is known as `copy-on-write`.
    fileprivate class Container {
        var resource: Resource
        var urlString: String? // memoized absoluteString
