From 4c06b013697d06b327f3c537e23181887aeab774 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Sat, 26 Nov 2011 15:30:38 +0000 Subject: [PATCH] Cache all computed type adapters. On one particularly violent test (issue 375) this improves performance by 77%. --- gson/src/main/java/com/google/gson/Gson.java | 9 +- .../main/java/com/google/gson/LruCache.java | 42 ---------- .../java/com/google/gson/LruCacheTest.java | 83 ------------------- 3 files changed, 8 insertions(+), 126 deletions(-) delete mode 100644 gson/src/main/java/com/google/gson/LruCache.java delete mode 100644 gson/src/test/java/com/google/gson/LruCacheTest.java diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java index fba8ccdb..f8b783b0 100644 --- a/gson/src/main/java/com/google/gson/Gson.java +++ b/gson/src/main/java/com/google/gson/Gson.java @@ -114,6 +114,9 @@ public final class Gson { } }; + private final Map, TypeAdapter> typeTokenCache + = Collections.synchronizedMap(new HashMap, TypeAdapter>()); + private final List factories; private final ConstructorConstructor constructorConstructor; @@ -328,7 +331,10 @@ public final class Gson { * deserialize {@code type}. */ public TypeAdapter getAdapter(TypeToken type) { - // TODO: cache? + TypeAdapter cached = typeTokenCache.get(type); + if (cached != null) { + return (TypeAdapter) cached; + } Map, FutureTypeAdapter> threadCalls = calls.get(); @SuppressWarnings("unchecked") // the key and value type parameters always agree @@ -344,6 +350,7 @@ public final class Gson { TypeAdapter candidate = factory.create(this, type); if (candidate != null) { call.setDelegate(candidate); + typeTokenCache.put(type, candidate); return candidate; } } diff --git a/gson/src/main/java/com/google/gson/LruCache.java b/gson/src/main/java/com/google/gson/LruCache.java deleted file mode 100644 index 7b39fbd7..00000000 --- a/gson/src/main/java/com/google/gson/LruCache.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.gson; - - -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * A cache that evict objects from the cache using an LRU (least recently used) - * policy. Object start getting evicted from the cache once the {@code maxCapacity} - * is reached. - * - * @author Inderjeet Singh - * @author Joel Leitch - */ -final class LruCache extends LinkedHashMap { - private final int maxCapacity; - - public LruCache(int maxCapacity) { - super(maxCapacity, 0.7F, true); - this.maxCapacity = maxCapacity; - } - - @Override protected boolean removeEldestEntry(Map.Entry entry) { - return size() > maxCapacity; - } -} diff --git a/gson/src/test/java/com/google/gson/LruCacheTest.java b/gson/src/test/java/com/google/gson/LruCacheTest.java deleted file mode 100644 index 56611268..00000000 --- a/gson/src/test/java/com/google/gson/LruCacheTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.gson; - - -import junit.framework.TestCase; - -/** - * Unit test for the {@link LruCache} class. - * - * @author Inderjeet Singh - * @author Joel Leitch - */ -public class LruCacheTest extends TestCase { - - public void testCacheHitAndMiss() throws Exception { - LruCache cache = new LruCache(3); - - String key = "key1"; - assertNull(cache.get(key)); - cache.put(key, 1); - assertEquals(1, cache.get(key).intValue()); - - String key2 = "key2"; - cache.put(key2, 2); - assertEquals(1, cache.get(key).intValue()); - assertEquals(2, cache.get(key2).intValue()); - } - - public void testCacheKeyOverwrite() throws Exception { - LruCache cache = new LruCache(3); - - String key = "key1"; - assertNull(cache.get(key)); - cache.put(key, 1); - assertEquals(1, cache.get(key).intValue()); - - cache.put(key, 5); - assertEquals(5, cache.get(key).intValue()); - } - - public void testCacheEviction() throws Exception { - LruCache cache = new LruCache(5); - - cache.put("key1", 1); - cache.put("key2", 2); - cache.put("key3", 3); - cache.put("key4", 4); - cache.put("key5", 5); - assertEquals(1, cache.get("key1").intValue()); - assertEquals(2, cache.get("key2").intValue()); - assertEquals(3, cache.get("key3").intValue()); - assertEquals(4, cache.get("key4").intValue()); - assertEquals(5, cache.get("key5").intValue()); - - // Access key1 to show key2 will be evicted (shows not a FIFO cache) - cache.get("key1"); - cache.get("key3"); - cache.put("key6", 6); - cache.put("key7", 7); - assertEquals(1, cache.get("key1").intValue()); - assertNull(cache.get("key2")); - assertEquals(3, cache.get("key3").intValue()); - assertNull(cache.get("key4")); - assertEquals(5, cache.get("key5").intValue()); - assertEquals(6, cache.get("key6").intValue()); - assertEquals(7, cache.get("key7").intValue()); - } -}