Re: Performance, Reflection, and Object Creation vs. Cacheing(was: Barracuda talk)

2001-08-29 Thread Calvin Yu

On Tue, 2001-08-28 at 00:02, Bryan Field-Elliot wrote:

 
 Also, you go on to say 'ditto for objection creation, and that it's 
 more expensive to cache an object than recreate it. Where are you 
 getting this information? It goes against the design considerations of 
 virtually every highly optimized Java system I've seen, including EJB 
 which goes to EXTREME lengths to reuse rather than recreate. You see the 
 same pattern with JSP custom tags (nowadays they are pooled), and you 
 even see the same thing in the Servlet spec design (which is to have one 
 multithreaded instance of the servlet class, rather than one per user 
 which would make more logical sense).

Object creation is rather fast, but that doesn't mean caching is always
frowned upon.  Caching for performance at the enterprise level is really
to reduce object initialization rather than object creation.  The
problem with EJBs, Tags, and Servlets is that they potentially do a lot
of up front initialization.  All three has to at least read an XML to
load some kind of deployment information, and then there are resources
(db, networking) that can be allocated by containers or developers.
Struts objects generally don't a lot of object initialization, therefore
isn't necessarily a really good candidate for caching.


Calvin




Re: Performance, Reflection, and Object Creation vs. Cacheing

2001-08-28 Thread Ted Husted

People I trust have said that they have run benchmarks that say
reflection 
can cost 5% to 10% more than direct method invocation.

http://archives.java.sun.com/cgi-bin/wa?A2=ind0001L=jsp-interestP=R35735

Now this is enough for some maven to put it on an optimization
punchlist, 
along with unrolling loops, and other time vs space trade-offs. But, 
personally, I don't find the need to unroll many loops in the
applications 
I write ;-)

So it's important to ask yourself whether 5% to 10% is a difference that 
makes a difference?

Also remember that in a real application, we are looking at one 
utility method, like BeanUtils.populate(), being threaded with all the 
assignments. I would think this is much more efficient than loading 
several hundred optimized methods just to manage direct method
invocations. 
BeanUtils.populate() also caches the descriptors so subsequent calls are 
even cheaper than the first.

Real-life optimizations are differences that make a real difference.
When 
the EJB platform was being designed, object creation ~did~ make a 
difference, and caching ~was~ vital. To an extent it still is, 
especially with deep hierarchies, like those many EJB applications 
find themselves using. But object creation and garbage collection in a
late 
model JVM is not what it used to be ;-) Progress!

Meanwhile, personally, I've started to build calls to
BeanUtils.populate()
into my own data transfer utilities. This lets me put a call deep inside
the resource layer that neatly turns an arbitrary ResultSet into a 
collection of arbitrary beans. It just matches the rset columns with the 
jbean properties.

// Transfer ResultSet to Collection of target beans **
if (resultSet!=null) {
collection = ResultSetUtils.getCollection(
target,resultSet);
}

Where ResultSetUtils does this 

public static void populate(Object bean,
ResultSet resultSet)
throws SQLException {
// Build a list of relevant column properties from this
resultSet
HashMap properties = new HashMap();
// Acquire resultSet MetaData
ResultSetMetaData metaData = resultSet.getMetaData();
int cols = metaData.getColumnCount();
// Scroll to next record and pump into hashmap
if (resultSet.next()) for (int i=1; i=cols ; i++) {
// :TODO: Let native types through
/*
int type = metaData.getType(i);
if ...
properties.put(metaData.getColumnName(i),
resultSet.getObject(i));
else
*/
properties.put(metaData.getColumnName(i),
resultSet.getString(i));
}
// Set the corresponding properties of our bean
try {
BeanUtils.populate(bean, properties);
} catch (Exception e) {
throw new SQLException(BeanUtils.populate threw  +
e.toString());
}
}

This can save hundreds of lines of code that would have otherwise have
been 
needed to write custom transfer utilities. (Been there, did that, not
fun.)

Of course, it works with more than just ResultSets. I wrote a similar
set
of utilities last week that turned a Lucene Hits list into a collection 
of beans. Sweet ;-)


Here are some other links from this list:

http://www.mail-archive.com/struts-user@jakarta.apache.org/msg12574.html

http://www.mail-archive.com/struts-user@jakarta.apache.org/msg13847.html

http://www.mail-archive.com/struts-user@jakarta.apache.org/msg13294.html

http://www.mail-archive.com/struts-user@jakarta.apache.org/msg13149.html

http://www.mail-archive.com/struts-user@jakarta.apache.org/msg11933.html

http://www.mail-archive.com/struts-user@jakarta.apache.org/msg02683.html

http://www.mail-archive.com/struts-user@jakarta.apache.org/msg00374.html


Other background links:

http://java.sun.com/j2se/1.4/docs/guide/reflection/

http://www-106.ibm.com/developerworks/library/introspect/index.html

http://www.javaworld.com/javaworld/jw-11-1999/jw-11-servlet_p.html

http://www.javaworld.com/javaworld/jw-11-1998/jw-11-batch_p.html

http://www.ddj.com/articles/1998/9801/9801c/9801c.htm

http://www.javaworld.com/javaworld/jw-09-1997/jw-09-indepth_p.html


Today's quote:

We should forget about small efficiencies, say about 97% of the time:
premature optimization is the root of all evil. - Donald Knuth

-T.


Bryan Field-Elliot wrote:
 This is incredibly important stuff! I'm sick to death of making tons of
 EJB entity beans, and then Value Objects (or data objects) which are
 very similar, and with Struts, Form Beans which again are very
 similar. Often I wish I could just use generic property sets (using
 HashMap, or any other generic collection). But I have resisted on
 principle, because I thought it would be a poor performer compared to
 straight Java variables and getters and setters. But here you are
 saying reflection is no longer a point of concern. What information
 have you got in this regard?
 

RE: Can BeanUtils support Timestamp datatype? (was: Performance,Reflection, and Object Creation vs. Cacheing)

2001-08-28 Thread Mindaugas Idzelis

Ted,
Wow!

I have to thank you for saving me from typing hundreds of lines of code
(well, I already wrote them -- now i'm gladly going to rip them out!) Using
BeanUtils to set properties of a bean from the column name of a ResultSet is
really smart. I've used your code fragment and it works great. However, I
noticed the TODO: says to let native types through. I would like to help
out on this part -- since I have a Timestamp datatype in my beans.

Now, are there any plans to make BeanUtils support setting a Timestamp
method? How would I go about writing an extension to BeanUtils to support
different datatypes?

I guess if I can't figure out how to set Timestamp datatypes in my beans,
I'll just change it to a string.

Mindaugas Idzelis



 -Original Message-
 From: Ted Husted [mailto:[EMAIL PROTECTED]]
 Sent: Tuesday, August 28, 2001 9:46 AM
 To: [EMAIL PROTECTED]
 Subject: Re: Performance, Reflection, and Object Creation vs. Cacheing


snip


 Meanwhile, personally, I've started to build calls to
 BeanUtils.populate()
 into my own data transfer utilities. This lets me put a call deep inside
 the resource layer that neatly turns an arbitrary ResultSet into a
 collection of arbitrary beans. It just matches the rset columns with the
 jbean properties.

 // Transfer ResultSet to Collection of target beans **
 if (resultSet!=null) {
   collection = ResultSetUtils.getCollection(
   target,resultSet);
 }

 Where ResultSetUtils does this

 public static void populate(Object bean,
 ResultSet resultSet)
 throws SQLException {
 // Build a list of relevant column properties from this
 resultSet
 HashMap properties = new HashMap();
 // Acquire resultSet MetaData
 ResultSetMetaData metaData = resultSet.getMetaData();
 int cols = metaData.getColumnCount();
 // Scroll to next record and pump into hashmap
 if (resultSet.next()) for (int i=1; i=cols ; i++) {
 // :TODO: Let native types through
 /*
 int type = metaData.getType(i);
 if ...
 properties.put(metaData.getColumnName(i),
 resultSet.getObject(i));
 else
 */
 properties.put(metaData.getColumnName(i),
 resultSet.getString(i));
 }
 // Set the corresponding properties of our bean
 try {
 BeanUtils.populate(bean, properties);
 } catch (Exception e) {
 throw new SQLException(BeanUtils.populate threw  +
 e.toString());
 }
 }

 This can save hundreds of lines of code that would have otherwise have
 been
 needed to write custom transfer utilities. (Been there, did that, not
 fun.)

 Of course, it works with more than just ResultSets. I wrote a similar
 set
 of utilities last week that turned a Lucene Hits list into a collection
 of beans. Sweet ;-)


snip






Re: Performance, Reflection, and Object Creation vs. Cacheing

2001-08-28 Thread Bryan Field-Elliot

Thanks for the insights Ted,

Please help me if I'm misinterpreting. But looking at your code, it 
seems like your populate still takes a plain Bean as it's destination, 
although it can use a property set (in this case, a ResultSet) as the 
source. This reduces the proliferation of Value (or other Bean) classes 
by 50%, but not 100%. In your scenario, which set of beans still need to 
be developed as plain old beans rather than dynamic sets of properties 
(e.g. the Entity beans, the Value Objects, or the Struts Form Beans, etc?)?

Thanks,
Bryan


Ted Husted wrote:


public static void populate(Object bean,
ResultSet resultSet)






Re: Performance, Reflection, and Object Creation vs. Cacheing

2001-08-28 Thread Ted Husted

To close the loop, it's helpful if a JavaBean can provide a Map of
itself. This way you can do things like

BeanUtils.populate(beanTarget,beanSource.toMap()). 

So I tend to define an interface that requires that and apply it to all
my beans, regardless of role. 

One consequence is that this will populate the properties that match,
and ignore any property that doesn't, so you don't have any parity
checking between the source and target. Though, usually this is a Good
Thing. For example, you can use the same bean class for a list and for
the detail, and just leave most of the properties null when it is being
used on the list.

Bryan Field-Elliot wrote:
 
 Thanks for the insights Ted,
 
 Please help me if I'm misinterpreting. But looking at your code, it
 seems like your populate still takes a plain Bean as it's destination,
 although it can use a property set (in this case, a ResultSet) as the
 source. This reduces the proliferation of Value (or other Bean) classes
 by 50%, but not 100%. In your scenario, which set of beans still need to
 be developed as plain old beans rather than dynamic sets of properties
 (e.g. the Entity beans, the Value Objects, or the Struts Form Beans, etc?)?
 
 Thanks,
 Bryan



RE: Performance, Reflection, and Object Creation vs. Cacheing

2001-08-28 Thread Mindaugas Idzelis

Ted,
Wow!

I have to thank you for saving me from typing hundreds of lines of code
(well, I already wrote them -- now i'm gladly going to rip them out!) Using
BeanUtils to set properties of a bean from the column name of a ResultSet is
really smart. I've used your code fragment and it works great. However, I
noticed the TODO: says to let native types through. I would like to help
out on this part -- since I have a Timestamp datatype in my beans.

Now, are there any plans to make BeanUtils support setting a Timestamp
method? How would I go about writing an extension to BeanUtils to support
different datatypes?

I guess if I can't figure out how to set Timestamp datatypes in my beans,
I'll just change it to a string.

Mindaugas Idzelis



 -Original Message-
 From: Ted Husted [mailto:[EMAIL PROTECTED]]
 Sent: Tuesday, August 28, 2001 9:46 AM
 To: [EMAIL PROTECTED]
 Subject: Re: Performance, Reflection, and Object Creation vs. Cacheing


snip


 Meanwhile, personally, I've started to build calls to
 BeanUtils.populate()
 into my own data transfer utilities. This lets me put a call deep inside
 the resource layer that neatly turns an arbitrary ResultSet into a
 collection of arbitrary beans. It just matches the rset columns with the
 jbean properties.

 // Transfer ResultSet to Collection of target beans **
 if (resultSet!=null) {
   collection = ResultSetUtils.getCollection(
   target,resultSet);
 }

 Where ResultSetUtils does this

 public static void populate(Object bean,
 ResultSet resultSet)
 throws SQLException {
 // Build a list of relevant column properties from this
 resultSet
 HashMap properties = new HashMap();
 // Acquire resultSet MetaData
 ResultSetMetaData metaData = resultSet.getMetaData();
 int cols = metaData.getColumnCount();
 // Scroll to next record and pump into hashmap
 if (resultSet.next()) for (int i=1; i=cols ; i++) {
 // :TODO: Let native types through
 /*
 int type = metaData.getType(i);
 if ...
 properties.put(metaData.getColumnName(i),
 resultSet.getObject(i));
 else
 */
 properties.put(metaData.getColumnName(i),
 resultSet.getString(i));
 }
 // Set the corresponding properties of our bean
 try {
 BeanUtils.populate(bean, properties);
 } catch (Exception e) {
 throw new SQLException(BeanUtils.populate threw  +
 e.toString());
 }
 }

 This can save hundreds of lines of code that would have otherwise have
 been
 needed to write custom transfer utilities. (Been there, did that, not
 fun.)

 Of course, it works with more than just ResultSets. I wrote a similar
 set
 of utilities last week that turned a Lucene Hits list into a collection
 of beans. Sweet ;-)


snip





Performance, Reflection, and Object Creation vs. Cacheing (was: Barracuda talk)

2001-08-27 Thread Bryan Field-Elliot

Ted,

I read your rebuttal tonight re: Barracuda, and I have questions about 
one of your points. Actually this has nothing to do with Barracuda:


-

Reflection

Every recent report I've seen says reflection is no longer a point of
concern. Ditto for object creation and garbage collection. The latest
advice is that is can be more expensive to cache an object that recreate
it.

-

This is incredibly important stuff! I'm sick to death of making tons of 
EJB entity beans, and then Value Objects (or data objects) which are 
very similar, and with Struts, Form Beans which again are very 
similar. Often I wish I could just use generic property sets (using 
HashMap, or any other generic collection). But I have resisted on 
principle, because I thought it would be a poor performer compared to 
straight Java variables and getters and setters. But here you are 
saying reflection is no longer a point of concern. What information 
have you got in this regard?

Also, you go on to say 'ditto for objection creation, and that it's 
more expensive to cache an object than recreate it. Where are you 
getting this information? It goes against the design considerations of 
virtually every highly optimized Java system I've seen, including EJB 
which goes to EXTREME lengths to reuse rather than recreate. You see the 
same pattern with JSP custom tags (nowadays they are pooled), and you 
even see the same thing in the Servlet spec design (which is to have one 
multithreaded instance of the servlet class, rather than one per user 
which would make more logical sense).

So, my apologies if this is off-topic of Struts, but these seem like 
very important and impactful design issues, relevent (even if 
peripherally) to good Struts design and development.

Thanks,

Bryan