I have been doing some more tweaking of the BeanUtil class to improve its performance.
This time I tried to remove duplicated hash lookups and other "costly" method calls
like Method.getParameterTypes.
I also made a change to the copy method as suggested by Robert on the list.
So the total improvements compared to 1.3RC2 are now:
Setting of non-string property: ~ 25% faster
Setting of string property: ~ 10-15% faster
Copy method: ~ 5-7% faster
Is it ok to commit these changes for the 1.3 version as well?
Cheers,
Dick
----------------------------
CVS diff follows:
Index: BeanUtil.java
===================================================================
RCS file: /cvsroot/opensymphony/webwork/src/main/webwork/util/BeanUtil.java,v
retrieving revision 1.34
diff -r1.34 BeanUtil.java
120c120,121
< PropertyDescriptor[] propertiesTo = getPropertyDescriptors(to.getClass());
---
> // Get the field map of the destination object once
> Map fieldMap = getFieldMapForClass(to.getClass());
124,127c125,131
< for (int j = 0; j < propertiesTo.length; j++)
< {
< PropertyDescriptor pdTo = propertiesTo[j];
< if (pdFrom.getName().equals(pdTo.getName()))
---
> // Look up the destination descriptor in the fieldMap
> PropertyDescriptor pdTo = (PropertyDescriptor)
>fieldMap.get(pdFrom.getName());
> if (pdTo != null)
> {
> Method readMethod = pdFrom.getReadMethod();
> Method writeMethod = pdTo.getWriteMethod();
> if (writeMethod != null && readMethod != null)
129,137c133,135
< Method readMethod = pdFrom.getReadMethod();
< Method writeMethod = pdTo.getWriteMethod();
< if (writeMethod != null && readMethod != null)
< {
< writeParameters[0] = pdFrom.getReadMethod().invoke(from,
readParameters);
< if (!(!includeNull && writeParameters[0] == null))
< pdTo.getWriteMethod().invoke(to, writeParameters);
< }
< break;
---
> writeParameters[0] = pdFrom.getReadMethod().invoke(from,
>readParameters);
> if (!(!includeNull && writeParameters[0] == null))
> pdTo.getWriteMethod().invoke(to, writeParameters);
165a164,167
> Map fieldMap = null;
> // Get the fieldMap of the destination object once
> if (keys.hasNext())
> fieldMap = getFieldMapForClass(to.getClass());
171c173
< setProperty(key, from.get(key), to);
---
> setProperty(key, from.get(key), to, fieldMap);
190a193
>
203a207,228
> if (obj == null)
> {
> throw new IllegalArgumentException("The target object for property '" +
>propertyName + "'. The target object needs to be initialized to a non-null value in
>order to set this property.");
> }
> Map fieldMap = getFieldMapForClass(obj.getClass());
> setProperty(propertyName, val, obj, fieldMap);
> }
>
> /**
> * Set a single JavaBean property value on an object.
> *
> * If the values in the map are of type String or String[] they may be converted
> * to the actual property type by the use of property editors.
> *
> * @param propertyName String representing the property or subproperty
> * @param val the value to set
> * @param obj the object to set the property on.
> * @param fieldMap Map with the PropertyDescriptors of the obj
> * @exception IllegalArgumentException
> */
> static protected void setProperty(String propertyName, Object val, Object obj,
>Map fieldMap) throws IllegalArgumentException
> {
207a233
> Map curFieldMap;
219,220c245,258
< PropertyDescriptor descriptor = getPropertyDescriptor(curSegment.getId(),
curObject);
<
---
> PropertyDescriptor descriptor;
> // Is the current object the same as the original one?
> // If not, get the field map for the new object
> if (curObject != obj)
> {
> curFieldMap = getFieldMapForClass(curObject.getClass());
> }
> else
> {
> curFieldMap = fieldMap;
> }
>
> // Lookup the descriptor in the curFieldMap
> descriptor = (PropertyDescriptor) curFieldMap.get(curSegment.getId());
354,355c392,393
< propertyEditors = newEditorMap;
< log.error("PropertyEditorManager.findEditor returned null for class: " +
clazz.getName());
---
> propertyEditors = newEditorMap;
> log.debug("PropertyEditorManager.findEditor returned null for class: " +
>clazz.getName());
498c536,538
< Class parameterClass = m.getParameterTypes()[0];
---
> // The getParameterTypes method is inefficient so we only call it once and
>save the result
> Class[] parameterClasses = m.getParameterTypes();
> Class parameterClass = parameterClasses[0];
515c555,556
< setStringValueWithPropertyEditor(obj, descriptor, value);
---
> // Set the value using a property editor. Pass in the parameterClass
> setStringValueWithPropertyEditor(obj, descriptor, value, parameterClass);
742a784
> * @param paramClass The parameter class used in the write method. Passed
>in for efficiency.
746c788
< static protected void setStringValueWithPropertyEditor(Object obj,
PropertyDescriptor descriptor, String[] values) throws IllegalArgumentException
---
> static protected void setStringValueWithPropertyEditor(Object obj,
>PropertyDescriptor descriptor, String[] values, Class paramClass) throws
>IllegalArgumentException
760,761c802
< Class[] paramClasses = m.getParameterTypes();
< Class paramClass = paramClasses[0];
---
> // The paramClass was passed to this method, now get the component
>type
763c804
< if (paramClass.getComponentType() != null)
---
> if (compType != null)
765c806
< Object a = Array.newInstance(paramClass.getComponentType(),
values.length);
-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
Opensymphony-webwork mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/opensymphony-webwork