Sudhir Jonathan
Sudhir Jonathan

Reputation: 17516

Creating objects makes the VM faster?

Look at this piece of code:

MessageParser parser = new MessageParser();
for (int i = 0; i < 10000; i++) {
    parser.parse(plainMessage, user);
}

For some reason, it runs SLOWER (by about 100ms) than

for (int i = 0; i < 10000; i++) {
    MessageParser parser = new MessageParser();
    parser.parse(plainMessage, user);
}

Any ideas why? The tests were repeated a lot of times, so it wasn't just random. How could creating an object 10000 times be faster than creating it once?

Upvotes: 2

Views: 290

Answers (4)

Christoph
Christoph

Reputation: 169553

What happens if you benchmark the first example while restricting the scope of parser, ie

{
    MessageParser parser = new MessageParser();
    for (int i = 0; i < 10000; i++) {
        parser.parse(plainMessage, user);
    }
}
// `parser` no longer visible

I'd expect this to be fastest as only one object has to be created, and the VM still knows that parser can be gc'd immediately after the loop.

Upvotes: 0

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147154

I have no idea what MessageParser does or where it comes from. It may be "leaking" internally. Another possibility is that the object become further away from the data created during the parsing. This means you are likely to get a TLA miss. Also if the the MessageParser keeps internal state, and moves into the tenured generation the GC mechanics of noting that it references new data can be a problem ("card scoring" is jargon that pops to mind).

Upvotes: 0

AlBlue
AlBlue

Reputation: 24040

Because Java has 'generational garbage collection' and can quickly identify (in the loop) that it doesn't re-use the same object/memory space, so the GC cost is virtually nil. On the other hand, your long-lived object will survive a generational pass over the nursery generation and have to be moved out to the main generation.

In summary, you can't really assume about performance without doing tests to measure it in place.

Upvotes: 10

Eric J.
Eric J.

Reputation: 150108

There may be some logic to clean up the internal state on a subsequent call to parser.

Did the GC run during your benchmark? It's fairly cheap to instantiate a new object, and it's not a fair comparison if you don't count the time to dispose of all of the objects you created in the faster case.

Upvotes: 0

Related Questions