Change JsScope to use LinkedHashMap instead of HashMap. This allows identifiers to be allocated obfuscated identifiers in the original order of their declaration, which produces a lot more common substrings in the obfuscated output which significantly improves gzip/deflate compression. Experimental Data using gzip -9 on cache.html files: Mail sample: 191614/197548 (3%) (with patch/without/% improved) Chronoscope: 1373800/1482204 (7.3%) Showcase: 1641005/1832098 (10.5%) git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5865 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java b/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java index 71489d6..de9552a 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java
@@ -24,7 +24,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.TreeMap; /** * A scope is a factory for creating and allocating @@ -162,11 +161,7 @@ * Returns an iterator for all the names defined by this scope. */ public Iterator<JsName> getAllNames() { - if (names.size() > 1) { - return new TreeMap<String, JsName>(names).values().iterator(); - } else { return names.values().iterator(); - } } /** @@ -206,7 +201,7 @@ */ protected JsName doCreateName(String ident, String shortIdent) { JsName name = new JsName(this, ident, shortIdent); - names = Maps.put(names, ident, name); + names = Maps.putOrdered(names, ident, name); return name; }
diff --git a/dev/core/src/com/google/gwt/dev/util/collect/Maps.java b/dev/core/src/com/google/gwt/dev/util/collect/Maps.java index 98fd25e..1cc6899 100644 --- a/dev/core/src/com/google/gwt/dev/util/collect/Maps.java +++ b/dev/core/src/com/google/gwt/dev/util/collect/Maps.java
@@ -17,6 +17,7 @@ import java.util.Collections; import java.util.Map; +import java.util.LinkedHashMap; /** * Utility methods for operating on memory-efficient maps. All maps of size 0 or @@ -117,6 +118,32 @@ } } + /** + * A variation of the put method which uses a LinkedHashMap. + */ + public static <K, V> Map<K, V> putOrdered(Map<K, V> map, K key, V value) { + switch (map.size()) { + case 0: + // Empty -> Singleton + return Collections.singletonMap(key, value); + case 1: { + if (map.containsKey(key)) { + return create(key, value); + } + // Singleton -> LinkedHashMap + Map<K, V> result = new LinkedHashMap<K, V>(); + result.put(map.keySet().iterator().next(), + map.values().iterator().next()); + result.put(key, value); + return result; + } + default: + // LinkedHashMap + map.put(key, value); + return map; + } + } + public static <K, V> Map<K, V> remove(Map<K, V> map, K key) { switch (map.size()) { case 0: