jGuru
Register Email     Password Forgot your
password?
HOME FAQS FORUMS DOWNLOADS ARTICLES PEERSCOPE LEARN

  Search   jGuru Search Help

Question What are the performance costs involved in Java reflection? E.g., looking up a method by name and then invoking it.
Derived from A question posed by Jim Nelson
Topics Java:Language, Java:Language:Reflection, Java:Implementation
Author Jef Newsom
Created Nov 6, 2000 Modified Nov 9, 2000


Answer
The lookup is quite expensive (greater than an order of magnitude increase), but the invocation is relatively cheap (factor of 2).

Here are some stats from the simple program below. Although not the most perfect benchmark, consider running this or creating a similar test to see how expensive it will be for you.

100000 regular method calls:2664 milliseconds.
100000 reflective method calls without lookup:4216 milliseconds.
100000 reflective method calls with lookup:45505 milliseconds.
1000000 regular method calls:27840 milliseconds.
1000000 reflective method calls without lookup:43863 milliseconds.
1000000 reflective method calls with lookup:470947 milliseconds.

Obviously, if the execution time of the method is relatively large, the invocation overhead becomes negligible, at which point consideration of the cost of complexity overhead of the reflective code versus the amount of flexibility/code reduction becomes the primary concern.

Consider writing a simple test to confirm the performance impact in your environment, such as:
Object object = new Object();
Class c = Object.class;

int loops = 100000;

long start = System.currentTimeMillis();
for( int i = 0; i < loops; i++ )
{
object.toString();
}
System.out.println( loops + " regular method calls:" + (System.currentTimeMillis() - start) + " milliseconds." );
java.lang.reflect.Method method = c.getMethod( "toString", null );

start = System.currentTimeMillis();
for( int i = 0; i < loops; i++ )
{
method.invoke( object, null );
}

System.out.println( loops + " reflective method calls without lookup:" + (System.currentTimeMillis() - start) + " milliseconds." );
start = System.currentTimeMillis();
for( int i = 0; i < loops; i++ )
{
method = c.getMethod( "toString", null );
method.invoke( object, null );
}
System.out.println( loops + " reflective method calls with lookup:" + (System.currentTimeMillis() - start) + " milliseconds." );


Is this item helpful?  yes  no     Previous votes   Yes: 5  No: 0



Comments and alternative answers

Comment on this FAQ entry

Performance has improved a lot
Per Velschow, Jan 22, 2003  [replies:6]
The benchmarks in this FAQ are more than 2 years old. I just ran the exact same tests to see what it would look like today. Here are the results:

100000 regular method calls:281 milliseconds.
100000 reflective method calls without lookup:297 milliseconds.
100000 reflective method calls with lookup:562 milliseconds.
1000000 regular method calls:2578 milliseconds.
1000000 reflective method calls without lookup:2782 milliseconds.
1000000 reflective method calls with lookup:5453 milliseconds.
10000000 regular method calls:25906 milliseconds.
10000000 reflective method calls without lookup:27891 milliseconds.
10000000 reflective method calls with lookup:54843 milliseconds.

It seems that either the Reflection API and/or the HotSpot compiler have improved a lot.

Is this item helpful?  yes  no     Previous votes   Yes: 1  No: 0



Reply to this answer/comment  Help  

Still lookup way of reflection calls are costly, though not that costly as 3 years back, still costlier than last year
saro ramki, Oct 5, 2004  [replies:5]
As on today(10/5/04) with the j2sdk1.4.2_03, the following is the result what I get. Compare 2003 result with this 2004 result. There is a improvement in the regular and non lookup calls. But the lookup calls takes more time than the 2003. Though the lookup calls aren't that bad like 3 years back, but once when you wanna tune your system to the best and reduce response time as less as possible, you might wanna consider avoiding the lookup way of reflection calls.

100000 regular method calls:203 milliseconds.
100000 reflective method calls without lookup:250 milliseconds.
100000 reflective method calls with lookup:938 milliseconds.

1000000 regular method calls:1828 milliseconds.
1000000 reflective method calls without lookup:2485 milliseconds.
1000000 reflective method calls with lookup:9343 milliseconds.

10000000 regular method calls:17766 milliseconds.
10000000 reflective method calls without lookup:24813 milliseconds.
10000000 reflective method calls with lookup:93611 milliseconds.


Is this item helpful?  yes  no     Previous votes   Yes: 1  No: 0



Reply to this answer/comment  Help  
Well, we're now in Feb 2007 and running JDK 1.6
Sidu Ponnappa, Feb 16, 2007  [replies:4]
I'm running JDK 1.6 (build 1.6.0-b105)
100000 regular method calls:78 milliseconds.
100000 reflective method calls without lookup:78 milliseconds.
100000 reflective method calls with lookup:203 milliseconds.

1000000 regular method calls:594 milliseconds.
1000000 reflective method calls without lookup:641 milliseconds.
1000000 reflective method calls with lookup:1984 milliseconds.

10000000 regular method calls:5063 milliseconds.
10000000 reflective method calls without lookup:6141 milliseconds.
10000000 reflective method calls with lookup:20093 milliseconds.

-Sidu

Is this item helpful?  yes  no     Previous votes   Yes: 1  No: 0



Reply to this answer/comment  Help  
Re: Well, we're now in Feb 2007 and running JDK 1.6
Darshan Bildikar, Jun 8, 2007  [replies:1]

I was able to pretty much replicate your results with an object with no args. But when I try a reflective call with parameters, I get the following output 10000000 regular method calls:31 milliseconds. 10000000 reflective method calls without lookup:1532 milliseconds. 10000000 reflective method calls with lookup:23609 milliseconds. Any idea how I can optimize



Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re[2]: Well, we're now in Feb 2007 and running JDK 1.6
Roman Tibin, Mar 26, 2008

I also found a diffent result when calling method with param, think it happens because hotspot optimizes regular method call in the loop.

I've changed param to a variable , and speed of regular call dropped to reflective call speed.

Code looks like this :
//regular call
for (int i = 0; i < loops; i++) {
testM.myMethod(""+i);
}
//reflective call
for (int i = 0; i < loops; i++) {
method.invoke(testM, ""+i);
}
//the method
public void myMethod(String string){
lSum += string.length();
}


Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
June of 2009 running JDK 1.6 update 12 on an Intel Core 2 Duo @ 2.33 Ghz
Chris Alexander, Jun 16, 2009  [replies:1]


See Other thoughts (below benchmarks)

(6/16/2009) & (jdk 1.6.0_12) & (intel Core 2 Duo @ 2.33 Ghz)

100000 regular method calls: 47 milliseconds.
100000 reflective method calls without lookup: 63 milliseconds.
100000 reflective method calls with lookup: 218 milliseconds.
-
1000000 regular method calls: 360 milliseconds.
1000000 reflective method calls without lookup: 453 milliseconds.
1000000 reflective method calls with lookup: 1562 milliseconds.
-
10000000 regular method calls: 3406 milliseconds.
10000000 reflective method calls without lookup: 4375 milliseconds.
10000000 reflective method calls with lookup: 15610 milliseconds.
=
=
=
100000 regular method calls: 31 milliseconds.
100000 reflective method calls without lookup: 47 milliseconds.
100000 reflective method calls with lookup: 156 milliseconds.
-
1000000 regular method calls: 328 milliseconds.
1000000 reflective method calls without lookup: 422 milliseconds.
1000000 reflective method calls with lookup: 1562 milliseconds.
-
10000000 regular method calls: 3407 milliseconds.
10000000 reflective method calls without lookup: 4281 milliseconds.
10000000 reflective method calls with lookup: 15640 milliseconds.


------------------
--Other Thoughts--
------------------

Unlike C or C++, java cannot measure the time spent on the CPU, only the Real Life time that passes. So depending on how fast your processor is, and what else you have running when you run this benchmark, your results may vary, but the trend is still the same.

Also, I modified the benchmark and put the whole benchmark in a loop that ran through the differant loop numbers (100,000; 1,000,000; and 10,000,000) and then put that loop inside another loop to run everything 2 times. This is important becase Java's Just-In-Time compiler profiles code before it optimizes it. This code runs acouple times with the hope that java will have a chance to optimize the code and run the optimized version before the benchmark ends. Although it did not make a big difference; the benchmark results for the regular method calls, that of the reflective method calles without lookup, and even the reflective with lookup on the 100,000 iteration benchmark of the seccond run performed better than that of the first run. Percentages below:

100000 regular method calls: 34%
100000 reflective method calls without lookup: 25.4%
100000 reflective method calls with lookup: 28.4%
-
1000000 regular method calls: 8%
1000000 reflective method calls without lookup: 6.8%
1000000 reflective method calls with lookup: Results Identical
-
10000000 regular method calls: Results Identical (within 1ms)
10000000 reflective method calls without lookup: 2.1%
10000000 reflective method calls with lookup: No Improvement - result fluctuation within margin of error (-0.2%)

These optimized results of the reflective code help make reflection look less like the retarted brother, and more like the very capable sibling....that happens to be...a little....special.

Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  
Re: June of 2009 running JDK 1.6 update 12 on an Intel Core 2 Duo @ 2.33 Ghz
Janice Chen, Sep 21, 2009
Test Env: Intel Core 2 Duo CPU @2.66GHz
100000 regular method calls:47 milliseconds.
100000 reflective method calls without lookup:31 milliseconds.
100000 reflective method calls with lookup:157 milliseconds.

1000000 regular method calls:312 milliseconds.
1000000 reflective method calls without lookup:453 milliseconds.
1000000 reflective method calls with lookup:1484 milliseconds.

10000000 regular method calls:3063 milliseconds.
10000000 reflective method calls without lookup:3984 milliseconds.
10000000 reflective method calls with lookup:14889 milliseconds.



Is this item helpful?  yes  no     Previous votes   Yes: 0  No: 0



Reply to this answer/comment  Help  


Ask A Question



 
Related Links

JavaLanguage FAQ

JavaLanguage Forum

Sun's Java Tutorial

What is the Java Platform

JavaWorld Magazine

IBM developerWorks

Java 2 SDK Tools and Utilities

The official Sun JavaDoc 1.1 documentation

The official Sun JavaDoc 1.2 documentation

The official Sun JavaDoc 1.3 documentation

The official Sun JavaDoc J2EE documentation

Wish List
Features
About jGuru
Contact Us

 



The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers