diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-10-29 21:46:44 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-10-29 21:46:44 -0400 |
commit | aa3f0e61a4f8f2837cd5147cfa72e61418d7b0d8 (patch) | |
tree | 530907135bfdf4b572b517b173be2b8fe50c9802 | |
parent | 5ebed57e1d6d7dc8230fa51e6cd34e22dc1f3a42 (diff) |
perf tweaks
-rw-r--r-- | src/clj/clojure/core.clj | 3 | ||||
-rw-r--r-- | src/clj/clojure/core_deftype.clj | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 25 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Keyword.java | 16 |
4 files changed, 33 insertions, 13 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 8d554847..479d1fd5 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -4443,7 +4443,8 @@ (assoc m (shift-mask shift mask (hash test)) te)) (sorted-map) case-map)] `(let [~ge ~e] - (case* ~ge ~shift ~mask ~(key (first hmap)) ~(key (last hmap)) ~default ~hmap)))) + (case* ~ge ~shift ~mask ~(key (first hmap)) ~(key (last hmap)) ~default ~hmap + ~(every? keyword? (keys case-map)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; helper files ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (alter-meta! (find-ns 'clojure.core) assoc :doc "Fundamental library of the Clojure language") diff --git a/src/clj/clojure/core_deftype.clj b/src/clj/clojure/core_deftype.clj index 0f496326..7a233820 100644 --- a/src/clj/clojure/core_deftype.clj +++ b/src/clj/clojure/core_deftype.clj @@ -51,7 +51,7 @@ [(conj i 'clojure.lang.ILookup) (conj m `(~'valAt [k#] (.valAt ~'this k# nil)) `(~'valAt [k# else#] - (condp identical? k# ~@(mapcat (fn [fld] [(keyword fld) fld]) + (case k# ~@(mapcat (fn [fld] [(keyword fld) fld]) base-fields) (get ~'__extmap k# else#))))] [i m])) diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 4ef28512..80458633 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -5615,15 +5615,17 @@ public static class CaseExpr extends UntypedExpr{ public final Expr defaultExpr; public final HashMap<Integer,Expr> tests; public final HashMap<Integer,Expr> thens; + public final boolean identity; public final int line; final static Method hashMethod = Method.getMethod("int hash(Object)"); + final static Method hashCodeMethod = Method.getMethod("int hashCode()"); final static Method equalsMethod = Method.getMethod("boolean equals(Object, Object)"); public CaseExpr(int line, Expr expr, int shift, int mask, int low, int high, Expr defaultExpr, - HashMap<Integer,Expr> tests,HashMap<Integer,Expr> thens){ + HashMap<Integer,Expr> tests,HashMap<Integer,Expr> thens, boolean identity){ this.expr = expr; this.shift = shift; this.mask = mask; @@ -5633,6 +5635,7 @@ public static class CaseExpr extends UntypedExpr{ this.tests = tests; this.thens = thens; this.line = line; + this.identity = identity; } public Object eval() throws Exception{ @@ -5658,7 +5661,10 @@ public static class CaseExpr extends UntypedExpr{ gen.visitLineNumber(line, gen.mark()); expr.emit(C.EXPRESSION, objx, gen); - gen.invokeStatic(UTIL_TYPE,hashMethod); + if(identity) + gen.invokeVirtual(OBJECT_TYPE,hashCodeMethod); + else + gen.invokeStatic(UTIL_TYPE,hashMethod); gen.push(shift); gen.visitInsn(ISHR); gen.push(mask); @@ -5670,8 +5676,15 @@ public static class CaseExpr extends UntypedExpr{ gen.mark(labels.get(i)); expr.emit(C.EXPRESSION, objx, gen); tests.get(i).emit(C.EXPRESSION, objx, gen); - gen.invokeStatic(UTIL_TYPE, equalsMethod); - gen.ifZCmp(GeneratorAdapter.EQ, defaultLabel); + if(identity) + { + gen.visitJumpInsn(IF_ACMPNE, defaultLabel); + } + else + { + gen.invokeStatic(UTIL_TYPE, equalsMethod); + gen.ifZCmp(GeneratorAdapter.EQ, defaultLabel); + } thens.get(i).emit(C.EXPRESSION,objx,gen); gen.goTo(endLabel); } @@ -5684,7 +5697,7 @@ public static class CaseExpr extends UntypedExpr{ } static class Parser implements IParser{ - //(case* expr shift mask low high default map<minhash, [test then]>) + //(case* expr shift mask low high default map<minhash, [test then]> identity?) //prepared by case macro and presumed correct //case macro binds actual expr in let so expr is always a local, //no need to worry about multiple evaluation @@ -5713,7 +5726,7 @@ public static class CaseExpr extends UntypedExpr{ (Integer)args.nth(3), (Integer)args.nth(4), analyze(C.EXPRESSION, args.nth(5)), - tests,thens); + tests,thens,args.nth(7) != RT.F); } } diff --git a/src/jvm/clojure/lang/Keyword.java b/src/jvm/clojure/lang/Keyword.java index 890f14d7..ac080923 100644 --- a/src/jvm/clojure/lang/Keyword.java +++ b/src/jvm/clojure/lang/Keyword.java @@ -17,10 +17,11 @@ import java.io.Serializable; import java.util.concurrent.ConcurrentHashMap; -public class Keyword implements IFn, Comparable, Named, Serializable { +public final class Keyword implements IFn, Comparable, Named, Serializable { private static ConcurrentHashMap<Symbol, Keyword> table = new ConcurrentHashMap(); public final Symbol sym; +final int hash; public static Keyword intern(Symbol sym){ Keyword k = new Keyword(sym); @@ -38,10 +39,11 @@ public static Keyword intern(String nsname){ private Keyword(Symbol sym){ this.sym = sym; + hash = sym.hashCode() + 0x9e3779b9; } -public int hashCode(){ - return sym.hashCode() + 0x9e3779b9; +public final int hashCode(){ + return hash; } public String toString(){ @@ -89,11 +91,15 @@ private Object readResolve() throws ObjectStreamException{ * @return the value at the key or nil if not found * @throws Exception */ -public Object invoke(Object obj) throws Exception{ +final public Object invoke(Object obj) throws Exception{ + if(obj instanceof ILookup) + return ((ILookup)obj).valAt(this); return RT.get(obj, this); } -public Object invoke(Object obj, Object notFound) throws Exception{ +final public Object invoke(Object obj, Object notFound) throws Exception{ + if(obj instanceof ILookup) + return ((ILookup)obj).valAt(this,notFound); return RT.get(obj, this, notFound); } |