Changeset 5135 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2012-03-30T16:34:15+02:00 (12 years ago)
Author:
simon04
Message:

see #6964 - speedup XmlObjectParser by caching fields/methods used to set values using reflection (speeds up preset parsing among others)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java

    r5130 r5135  
    134134                }
    135135                for (int i = 0; i < a.getLength(); ++i) {
    136                     setValue(a.getQName(i), a.getValue(i));
     136                    setValue(mapping.get(qname), a.getQName(i), a.getValue(i));
    137137                }
    138138                if (mapping.get(qname).onStart) {
     
    147147            if (mapping.containsKey(qname) && !mapping.get(qname).onStart) {
    148148                report();
    149             } else if (characters != null && !current.isEmpty()) {
    150                 setValue(qname, characters.toString().trim());
     149            } else if (mapping.containsKey(qname) && characters != null && !current.isEmpty()) {
     150                setValue(mapping.get(qname), qname, characters.toString().trim());
    151151                characters  = new StringBuilder(64);
    152152            }
     
    171171        }
    172172
    173         private void setValue(String fieldName, String value) throws SAXException {
     173        private void setValue(Entry entry, String fieldName, String value) throws SAXException {
     174            if (entry == null) {
     175                throw new NullPointerException("entry cannot be null");
     176            }
    174177            if (fieldName.equals("class") || fieldName.equals("default") || fieldName.equals("throw") || fieldName.equals("new") || fieldName.equals("null")) {
    175178                fieldName += "_";
     
    177180            try {
    178181                Object c = current.peek();
    179                 Field f = null;
    180                 try {
    181                     f = c.getClass().getField(fieldName);
    182                 } catch (NoSuchFieldException e) {
    183                     if(fieldName.startsWith(lang))
    184                     {
    185                         String locfieldName = "locale_" +
    186                                 fieldName.substring(lang.length());
    187                         try {
    188                             f = c.getClass().getField(locfieldName);
    189                         } catch (NoSuchFieldException ex) {
    190                         }
    191                     }
    192                 }
    193                 if (f != null && Modifier.isPublic(f.getModifiers())) {
     182                Field f = entry.getField(fieldName);
     183                if (f == null && fieldName.startsWith(lang)) {
     184                    f = entry.getField("locale_" + fieldName.substring(lang.length()));
     185                }
     186                if (f != null && Modifier.isPublic(f.getModifiers()) && String.class.equals(f.getType())) {
    194187                    f.set(c, getValueForClass(f.getType(), value));
    195188                } else {
    196                     if(fieldName.startsWith(lang))
    197                     {
     189                    if (fieldName.startsWith(lang)) {
    198190                        int l = lang.length();
    199                         fieldName = "set" + fieldName.substring(l,l+1).toUpperCase() + fieldName.substring(l+1);
     191                        fieldName = "set" + fieldName.substring(l, l + 1).toUpperCase() + fieldName.substring(l + 1);
     192                    } else {
     193                        fieldName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    200194                    }
    201                     else
    202                     {
    203                         fieldName = "set" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
    204                     }
    205                     Method[] methods = c.getClass().getMethods();
    206                     for (Method m : methods) {
    207                         if (m.getName().equals(fieldName) && m.getParameterTypes().length == 1) {
    208                             m.invoke(c, new Object[]{getValueForClass(m.getParameterTypes()[0], value)});
    209                             return;
    210                         }
     195                    Method m = entry.getMethod(fieldName);
     196                    if (m != null) {
     197                        m.invoke(c, new Object[]{getValueForClass(m.getParameterTypes()[0], value)});
    211198                    }
    212199                }
     
    240227        boolean onStart;
    241228        boolean both;
     229        private final Map<String, Field> fields = new HashMap<String, Field>();
     230        private final Map<String, Method> methods = new HashMap<String, Method>();
     231
    242232        public Entry(Class<?> klass, boolean onStart, boolean both) {
    243             super();
    244233            this.klass = klass;
    245234            this.onStart = onStart;
    246235            this.both = both;
     236        }
     237
     238        Field getField(String s) {
     239            if (fields.containsKey(s)) {
     240                return fields.get(s);
     241            } else {
     242                try {
     243                    Field f = klass.getField(s);
     244                    fields.put(s, f);
     245                    return f;
     246                } catch (NoSuchFieldException ex) {
     247                    fields.put(s, null);
     248                    return null;
     249                }
     250            }
     251        }
     252
     253        Method getMethod(String s) {
     254            if (methods.containsKey(s)) {
     255                return methods.get(s);
     256            } else {
     257                for (Method m : klass.getMethods()) {
     258                    if (m.getName().equals(s) && m.getParameterTypes().length == 1) {
     259                        methods.put(s, m);
     260                        return m;
     261                    }
     262                }
     263                methods.put(s, null);
     264                return null;
     265            }
    247266        }
    248267    }
Note: See TracChangeset for help on using the changeset viewer.