Hey,

did a little test (see code below) to check how much expensive is the
creation of a CacheKey, implementing 2 different algorithms
(MarshalledObject and reflection).
Here the results (running on laptop PII300 128MB WIN2K JDK 1.3) for the
creation of 10000 objects:

PK: 4.7-4.8 ms (for comparison)
MarshalledObject: 4245-4285 ms
Key (reflection): 2785-2825 ms

Well, not the fastest results IMHO, both for MO and reflection.
Given that a CacheKey is created for each bean creation or for each PK
returned by a finder method, a finder that returns a Collection of 10000
beans will take 4.2 (2.8) seconds more than what is needed. Is that
acceptable in your opinion ?

Marc, I've remember you talking about a sequencial-like CacheKey, is it
correct ? What is the idea ?

Simon

import java.lang.reflect.*;

public class CacheKeyTest
{
        public static void main(String[] args) 
        {
                int n = 10000;
                PK pk = new PK(10, 100L, true, "SIMON", 1.0D, '1', 0.1F);
                long start = System.currentTimeMillis();
                for (int j = 0; j < n; ++j)
                {
                        try 
                        {
                                java.rmi.MarshalledObject mo = new
java.rmi.MarshalledObject(pk);
//                              int hash = mo.hashCode();
                        } 
                        catch (java.io.IOException x) {}
                }
                long end = System.currentTimeMillis();
                System.out.println(n + " MO creation took: " + (end-start));

                int pkn = n * 1000;
                start = System.currentTimeMillis();
                for (int j = 0; j < pkn; ++j)
                {
                        PK p = new PK(10, 100L, true, "SIMON", 1.0D, '1',
0.1F);
                }
                end = System.currentTimeMillis();
                System.out.println(pkn + " PK creation took: " +
(end-start));

//              System.out.println(new Key(pk));
                int kn = n;
                start = System.currentTimeMillis();
                for (int j = 0; j < kn; ++j)
                {
                        Key k = new Key(pk);
                }
                end = System.currentTimeMillis();
                System.out.println(kn + " PK creation took: " +
(end-start));

        }
}

class PK 
{
        public int m_i;
        public long m_l;
        public boolean m_b;
        public String m_s;
        public double m_d;
        public char m_c;
        public float m_f;

        PK(int i, long l, boolean b, String s, double d, char c, float f) 
        {
                m_i = i;
                m_l = l;
                m_b = b;
                m_s = s;
                m_d = d;
                m_c = c;
                m_f = f;
        }
}

class Key
{
        private int m_hash;
        private Object m_id;
        private StringBuffer m_buffer;
        private static String m_separator = "|";
        
        Key(Object id) 
        {
                m_id = id;
                Class cls = id.getClass();
                if (cls == Object.class || isPrimitiveWrapperOrString(cls)) 
                {
                        m_hash = id.hashCode();
                }
                else 
                {
                        m_buffer = new StringBuffer();
                        m_buffer.append(cls.getName());
                        computeHash(cls);
                }
        }
        public int hashCode() {return m_hash;}
        public boolean equals(Object o) 
        {
                if (this == o) {return true;}
                if (o instanceof Key) 
                {
                        Key other = (Key)o;
                        if (m_buffer != null && other.m_buffer != null)
                        {
                                return
m_buffer.toString().equals(other.m_buffer.toString());
                        }
                        return m_id.equals(other.m_id);
                }
                return false;
        }
        public String toString() {return m_buffer == null ? super.toString()
+ "#" + m_hash + "|" + m_id.toString(): m_buffer.toString() + "#" + m_hash +
"|" + m_id.toString();}
        private void computeHash(Class cls) 
        {
                if (cls == Object.class) {return;}
                Field[] fields = cls.getFields();
                int l = fields.length;
                for (int i = 0; i < l; ++i)
                {
                        Field f = fields[i];
                        Class c = f.getType();
                        if (c.isPrimitive() ||
isPrimitiveWrapperOrString(c))
                        {
                                m_buffer.append(m_separator);
                                try {m_buffer.append(f.get(m_id));}
                                catch (IllegalAccessException ignored) {}
                        }
                        else {computeHash(c);}
                }
                m_hash = m_buffer.toString().hashCode();
        }
        private boolean isPrimitiveWrapperOrString(Class c) 
        {
                // Ordered by most common
                if (c == String.class ||
                        c == Integer.class ||
                        c == Boolean.class ||
                        c == Long.class ||
                        c == Double.class ||
                        c == Float.class ||
                        c == Character.class ||
                        c == Byte.class ||
                        c == Short.class) {return true;}
                return false;
        }
}



Reply via email to