performance of Class.forname()?

Discussion in 'Java' started by Ahmed Moustafa, Jul 20, 2003.

  1. In a couple of performance articles, it is recommended to dynamically
    load classes as needed with Class.forname().

    Why?
    Ahmed Moustafa, Jul 20, 2003
    #1
    1. Advertising

  2. Ahmed Moustafa

    Roedy Green Guest

    On Sun, 20 Jul 2003 03:42:05 GMT, Ahmed Moustafa <>
    wrote or quoted :

    >In a couple of performance articles, it is recommended to dynamically
    >load classes as needed with Class.forname().


    I can't think of a performance reason.

    Java does not load classes until they are needed, whether or not you
    use Class.forName.

    The usual reason for using it is to allow plugin classes that are
    created later.

    For example, I use them in my HTMLMacro skeleton. You can add new
    Macros written in Java without recompiling the macro expansion shell
    engine.

    I also use them in the Holiday Calculator. You can add more holidays
    just by implementing an interface.

    In static native compilation, Class.forName screws things up. New
    classes come in out of the blue that were not present for global
    optimisation at compile time.



    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
    Roedy Green, Jul 20, 2003
    #2
    1. Advertising

  3. Lothar Kimmeringer wrote:
    > On Sun, 20 Jul 2003 03:42:05 GMT, Ahmed Moustafa wrote:
    >
    >
    >>In a couple of performance articles, it is recommended to dynamically
    >>load classes as needed with Class.forname().
    >>
    >>Why?

    >
    >
    > There should be a reason in the articles. IMHO it's better to
    > initialize instances the "normal" way (using new) to be able
    > to find errors during compile-time. A
    >
    > MyClass myClass = Class.forName("Myclass");
    >
    > will lead to a ClassNotFoundException during runtime. A
    >
    > MyCLass myClass = new Myclass()
    >
    > allows the compiler to tell you that there is no class with
    > name Myclass.
    >
    > And I'm quite sure that you will lose more time in a
    > constructor being implemented inefficently that you
    > will get with using forName instead of new.
    >
    > Do you have a link to one of these "couple of" articles?


    http://www.cs.utexas.edu/users/toktb/J-Breeze/javaperform.tips.html#classes
    http://patrick.net/jpt/
    Ahmed Moustafa, Jul 20, 2003
    #3
  4. Ahmed Moustafa

    Roedy Green Guest

    On Sun, 20 Jul 2003 15:29:02 GMT, Ahmed Moustafa <>
    wrote or quoted :

    >http://patrick.net/jpt/


    states:

    "Unless a method is final, it is located on demand at runtime. Methods
    are encoded in .class files as strings, not addresses. This allows
    them to be relocated easily and makes overflow attacks harder, since
    you don't know where any particular method is going to be. But this
    also means a lot of runtime overhead of string parsing and method
    location is going on at runtime, unlike C, where execution jumps
    directly to the address compiled into the code."

    This is misleading. It gives the impression that methods are linked
    with some sort of hashtable on every call. Even in the most primitive
    interpreted systems, methods links are converted to direct address
    links on first call. This is partly why you can't easily replace class
    files on the fly.
    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
    Roedy Green, Jul 20, 2003
    #4
  5. Ahmed Moustafa

    Roedy Green Guest

    On Sun, 20 Jul 2003 15:29:02 GMT, Ahmed Moustafa <>
    wrote or quoted :

    >http://patrick.net/jpt/


    I think the explanation is that "Patrick" has gleaned his knowledge by
    pragramatic experiments and made some guesses as to how the JVM worked
    inside, but did not check to see if he was correct. I think He
    imagines that Class.forName will save RAM. He probably thinks that
    all classes in the jar are loaded, whether they are used or not by the
    ordinary mechanism.

    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
    Roedy Green, Jul 20, 2003
    #5
  6. Ahmed Moustafa

    Adam Maass Guest

    "Ahmed Moustafa" <> wrote:
    > In a couple of performance articles, it is recommended to dynamically
    > load classes as needed with Class.forname().
    >
    > Why?
    >


    Under normal operation, the JVM does not load classes into main memory until
    they are needed, often in response to a call to the new operator. Delaying
    class loading like this may result in a slowdown as the needed classes are
    loaded (but only the first time they are needed).

    I am guessing that the articles (without any references) say that using
    Class.forName on the classes may avoid the dynamic loading that happens the
    first time they are needed.


    While this is true, I wouldn't recommend it unless you can prove two things:

    1) Dynamicly loading classes as they are needed results in an unacceptable
    slowdown,
    2) Forcing the classes to load before they are needed with Class.forName
    actually makes things better.

    I wager that this is a tough test to meet. In my experience, many classes
    are loaded long before I naively expect them to be: this is because the JVM
    traces static class references in the entire class file as it is being
    loaded and recursively loads all of the classes needed to resolve the
    symbols. Additionally, the strategy of forcing classes to load with
    Class.forName works only when there is a long delay between the time the
    forced-load happens (often at startup) and the time the classes are actually
    needed. The strategy is fragile: it relies on some list of classes that need
    to be pre-loaded; that list needst to be generated and maintained if it is
    to be of any use. And since the GC can unload classes if they don't have any
    instances or active threads in any method, the strategy is likely to fail to
    achieve its purpose anyway.


    -- Adam Maass
    Adam Maass, Jul 21, 2003
    #6
  7. Adam Maass wrote:
    > "Ahmed Moustafa" <> wrote:
    >
    >
    > I wager that this is a tough test to meet. In my experience, many classes
    > are loaded long before I naively expect them to be: this is because the JVM
    > traces static class references in the entire class file as it is being
    > loaded and recursively loads all of the classes needed to resolve the
    > symbols. Additionally, the strategy of forcing classes to load with
    > Class.forName works only when there is a long delay between the time the
    > forced-load happens (often at startup) and the time the classes are actually
    > needed. The strategy is fragile: it relies on some list of classes that need
    > to be pre-loaded; that list needst to be generated and maintained if it is
    > to be of any use. And since the GC can unload classes if they don't have any
    > instances or active threads in any method, the strategy is likely to fail to
    > achieve its purpose anyway.
    >


    The GC can only unload classes where the classloader for a class is
    unreachable. This is a change from the early Java releases where GC did
    unload individual classes. This was changed to avoid surprises from
    changes in static fields (returning to their initial state).

    Mark Thornton
    Mark Thornton, Jul 21, 2003
    #7
  8. Ahmed Moustafa

    pete kirkham Guest

    > http://www.cs.utexas.edu/users/toktb/J-Breeze/javaperform.tips.html#classes

    includes:
    > Classes/Interface
    > * replace generic standard classes with faster implementations specific to application
    > * create subclasses to override methods with faster versions
    > * program using interfaces, so that actual structure can be easily swapped to improve performance

    ....
    > * dynamically load class with Class.forname() (why? no reason given)


    'No reason given'- but how else do you do the first three dynamically?

    > String
    >
    > * use char[] array directly to create String rather than StringBuffer
    > * convert string to char[] to process character, rather than using charAt()

    Both require an array copy.

    for (int k=0; k<10000; k++) {
    for (int j=0; j<strings.length; j++) {
    // converting to char array >>>>>
    char[] data = strings[j].toCharArray();
    for (int l=0; l<data.length; l++) {
    really = really && data[l] == 'j';
    }
    }
    }
    runs in around 17ms where strings is an array of ten Strings of length 7.

    for (int i=0; i<10; i++) {
    start_time = System.currentTimeMillis();
    for (int k=0; k<10000; k++) {
    for (int j=0; j<strings.length; j++) {
    String data = strings[j];
    for (int l=0; l<data.length(); l++) {
    // calling charAt >>>>>
    really = really && data.charAt(l) == 'j';
    }
    }
    }
    runs in around 5ms with the same data (java 1.4.1_01-39 on OS X)


    Pete
    pete kirkham, Jul 21, 2003
    #8
  9. Ahmed Moustafa

    Jon A. Cruz Guest

    pete kirkham wrote:
    >> http://www.cs.utexas.edu/users/toktb/J-Breeze/javaperform.tips.html#classes
    >>

    >
    >
    > includes:
    > > Classes/Interface

    >
    >> * replace generic standard classes with faster implementations
    >> specific to application
    >> * create subclasses to override methods with faster versions
    >> * program using interfaces, so that actual structure can be easily
    >> swapped to improve performance

    >
    > ...
    >
    >> * dynamically load class with Class.forname() (why? no reason given)

    >
    >
    > 'No reason given'- but how else do you do the first three dynamically?
    >


    Hmmm... let me jump in here with no context and just try to hack some
    answer...

    OK. The first one is easy.

    Document myDoc = new MyTunedForMyAppDoc();
    JTextArea area = new JTextArea( myDoc );

    Bingo!
    :)

    Or
    Document myDoc = new MyStupidButOnly16KDoc();

    etc.

    * the second:
    Basically the same thing

    Gee. And same on the third.


    All three of those can be implemented through several standard patterns,
    including factory methods and singletons. No class.forName() required.




    > runs in around 17ms where strings is an array of ten Strings of length 7.


    > runs in around 5ms with the same data (java 1.4.1_01-39 on OS X)


    So the "optimized" version is more than 3 times slower on your machine?
    Jon A. Cruz, Jul 22, 2003
    #9
  10. Ahmed Moustafa

    Chris Guest

    Jon Skeet <> wrote in message news:<>...
    > > I only has a dozen or so classes, but I dummied up a 100 string
    > > comparisons and it was still faster than dynamic loading and
    > > newInstance().

    >
    > Out of interest, which VM was that with? It'd be interesting to see the
    > results on various VMs, as I believe 1.4 is significantly faster at
    > this than 1.3.1.


    This was on 1.3.1, but I've just installed 1.4.2 and will be
    re-compiling this evening, I've still got the alternative code so I'll
    post the results tomorrow.

    - sarge
    Chris, Jul 22, 2003
    #10
  11. "I substituted a factory class for the dynamic loader and got a 100%
    increase in the parsing part of the descriptor loader."

    Not sure what you're measuring here. If you don't include the time taken to
    statically load the referenced classes (presumeably as part of the
    class-loading of the parser itself), then you are only comparing dynamically
    loading classes vs having them loaded already, which isn't really a fair
    comparison.

    As mentioned earlier the time taken to statically load the classes may
    appear much earlier in your program load time, but will still count against
    overall performance.

    You could try pre-loading the Class objects into a Map before you started
    parsing and get a better comparison over the newInstance() vs new Classname
    performance though. Otherwise I think you'd have to measure the performance
    gain over the whole run-time of the program (or at least up until the
    parsing has completed) to get a more accurate static vs dynamic loading
    comparison.

    Regards,
    Peter

    "Chris" <> wrote in message
    news:...
    > This might not be exactly pertinent to loading of classes, but it's a
    > related issue...
    >
    > One of my current projects has an XML descriptor that defines how the
    > various objects in my data model are connected.
    >
    > i.e.
    >
    > <thing class="a.b.c.whatever" ...>
    >
    > Originally I had the classes for these objects loaded/created using
    > Class.forName() and newInstance().
    >
    > When I came to optimising the software, I found that the loader was
    > quite slow, even after discounting the overhead of the XML
    > loader/parser.
    >
    > I substituted a factory class for the dynamic loader and got a 100%
    > increase in the parsing part of the descriptor loader.
    >
    > i.e.
    >
    > if( type.equals( "a" ) )
    > {
    > return new A( ... )
    > }
    > else
    > if( type.equals( "b" ) )
    > {
    > return new B( ... )
    > }
    > etc
    >
    > So even with the overhead of numerous string comparisons the factory
    > method was twice as fast.
    >
    > I only has a dozen or so classes, but I dummied up a 100 string
    > comparisons and it was still faster than dynamic loading and
    > newInstance().
    >
    > - sarge
    >
    Peter McDonnell, Jul 22, 2003
    #11
  12. Ahmed Moustafa

    pete kirkham Guest

    Jon A. Cruz wrote:

    > pete kirkham wrote:
    >
    >>> http://www.cs.utexas.edu/users/toktb/J-Breeze/javaperform.tips.html#classes
    >>>

    >>
    >>
    >>
    >> includes:
    >> > Classes/Interface

    >>
    >>> * replace generic standard classes with faster implementations
    >>> specific to application
    >>> * create subclasses to override methods with faster versions
    >>> * program using interfaces, so that actual structure can be
    >>> easily swapped to improve performance

    >>
    >>
    >> ...
    >>
    >>> * dynamically load class with Class.forname() (why? no reason given)

    >>
    >>
    >>
    >> 'No reason given'- but how else do you do the first three dynamically?
    >>

    >
    > Hmmm... let me jump in here with no context and just try to hack some
    > answer...
    >
    > OK. The first one is easy.
    >
    > Document myDoc = new MyTunedForMyAppDoc();
    > JTextArea area = new JTextArea( myDoc );

    ....
    > Or
    > Document myDoc = new MyStupidButOnly16KDoc();


    Is this dynamic? In this you have replaced the implementation of
    Document using a statically linked class. Can the client of your code
    choose to replace your implementation of Document with one tuned for
    _their_ specific application, or are they stuck with your solution based
    on _your_ assumptions as to what to optimise? If this is part a library,
    have you enabled the client to apply the three optimisation techniques
    listed?

    > All three of those can be implemented through several standard patterns,
    > including factory methods and singletons. No class.forName() required.


    How do you implement these patterns dynamically, by which I mean
    allowing the client to replace the default implementation with one
    optimised for their application, without using Class.forName() (or
    hacking bytecode/calling the compiler etc.)?

    > So the "optimized" version is more than 3 times slower on your machine?


    That indeed was the point. Trust the profiler, not the mythology.


    Pete
    pete kirkham, Jul 22, 2003
    #12
  13. Ahmed Moustafa

    Jon A. Cruz Guest

    pete kirkham wrote:
    > Is this dynamic? In this you have replaced the implementation of
    > Document using a statically linked class. Can the client of your code
    > choose to replace your implementation of Document with one tuned for
    > _their_ specific application, or are they stuck with your solution based
    > on _your_ assumptions as to what to optimise? If this is part a library,
    > have you enabled the client to apply the three optimisation techniques
    > listed?


    Sorry. That's what I get for posting when too tired.

    You can use those to hide the Class.forName().

    One good example is how to get a SAX parser.


    >
    >
    > That indeed was the point. Trust the profiler, not the mythology.
    >


    And remember, it might differ on each system. What you do to help on one
    can hurt on another.
    Jon A. Cruz, Jul 23, 2003
    #13
  14. Hello Ahmed

    Ahmed Moustafa <>, Sun, 20 Jul 2003 03:42:05 +0000:

    > In a couple of performance articles, it is recommended to dynamically
    > load classes as needed with Class.forname().
    >
    > Why?


    It's very dependent on a lot of factors, just like most of the other
    optimisations. There aren't many hard and fast rules. For one thing, I
    would not trust an article that is date around the release data of java
    1.2. There have been a lot of changes in the JVM itself since then.

    The Class.forName() argument probably holds for the user, when several
    things like 1) The application code is HUGE, and 2) The code is loaded over
    the network, are true.

    If the code base is huge, and you start a program, you must remember that
    you have a programmed a big class tree. So when you load the first class,
    the class loader will try to load all classes referenced by the first call
    and link them.

    If everything is linked statically, then the JVM will load
    and link every single class of your program before your application even
    starts. That can be perceived as a huge performance hit, because the
    application takes longer to start. (I'm almost sure this is the case with
    Swing applets).

    If you can divide the application in several parts where
    certain parts are started by an object that is instantiated by a class
    loaded with Class.forName, everything starting at that class is not loaded
    until the code actually executes the Class.forName call. Combine that fact
    with low-speed connections and you have to wait a long time. There may be
    other issues that aren't so apparent.

    Greets
    Bhun.
    dhek bhun kho, Jul 27, 2003
    #14
  15. Ahmed Moustafa

    Chris Smith Guest

    Jon A. Cruz wrote:
    > pete kirkham wrote:
    > > Is this dynamic? In this you have replaced the implementation of
    > > Document using a statically linked class. Can the client of your code
    > > choose to replace your implementation of Document with one tuned for
    > > _their_ specific application, or are they stuck with your solution based
    > > on _your_ assumptions as to what to optimise? If this is part a library,
    > > have you enabled the client to apply the three optimisation techniques
    > > listed?

    >
    > Sorry. That's what I get for posting when too tired.
    >
    > You can use those to hide the Class.forName().
    >
    > One good example is how to get a SAX parser.


    No, no, no! Jon, you were right before. Class.forName is not required
    to provide flexibility to clients in tuning performance. In fact, a far
    better way to do this in the general case is to define interfaces and
    let clients specify the correct behavior in code by providing an
    implementation of that interface. If new objects need to be created,
    passing in factory interfaces can do the trick.

    Class.forName comes in when you want to be able to modify the
    configuration of an application without making code changes. That's
    really a somewhat rare need; it's usefulness has largely been
    manufactured by Sun. By definition in the case cited above, it's a Java
    programmer that wrote that code, and it's a Java programmer that wants
    to use it, so the link can be made in Java, just as easily as in some
    properties file in a META-INF directory.

    I've long had this vision of Sun sitting around thinking "what does Java
    have that other popular languages don't? Oh, reflection! Let's start
    pushing it like it's the solution to all the world's problems!", and so
    was the nightmare of J2EE born. It's rather unfortunate -- nay, tragic
    -- that this has now spread into J2SE classes like a hideous cancer!

    --
    www.designacourse.com
    The Easiest Way to Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
    Chris Smith, Jul 29, 2003
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. iksrazal

    Re: Class.forname() vs clone()

    iksrazal, Jun 27, 2003, in forum: Java
    Replies:
    0
    Views:
    1,604
    iksrazal
    Jun 27, 2003
  2. learningjava
    Replies:
    1
    Views:
    533
    Anton Spaans
    Oct 27, 2003
  3. H.MuthuKumaraRajan

    .class and Class.forName

    H.MuthuKumaraRajan, Nov 6, 2003, in forum: Java
    Replies:
    11
    Views:
    1,729
    H.MuthuKumaraRajan
    Nov 7, 2003
  4. cyril
    Replies:
    2
    Views:
    3,858
    cyril
    Aug 25, 2004
  5. Madni
    Replies:
    1
    Views:
    5,880
Loading...

Share This Page