summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2009-10-29 21:46:44 -0400
committerRich Hickey <richhickey@gmail.com>2009-10-29 21:46:44 -0400
commitaa3f0e61a4f8f2837cd5147cfa72e61418d7b0d8 (patch)
tree530907135bfdf4b572b517b173be2b8fe50c9802
parent5ebed57e1d6d7dc8230fa51e6cd34e22dc1f3a42 (diff)
perf tweaks
-rw-r--r--src/clj/clojure/core.clj3
-rw-r--r--src/clj/clojure/core_deftype.clj2
-rw-r--r--src/jvm/clojure/lang/Compiler.java25
-rw-r--r--src/jvm/clojure/lang/Keyword.java16
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);
}