Tiny object performance overhead

Appearantly this object is expensive to construct and/or initialize:


public class Vec3
{
  public float x,y,z;
}

See my benchmark: compare “new object” (1354ms) and “used object” (447ms).

Ya gotta be *really careful with micro-benchmarks in java. Its very very easy to get meaningles results.

I’m swamped now but if I find time later Ill take a look at this particular example.

I’m fully aware of that, and have run into this in real-world applications, and turned it into a bechmark to show the results with you guys without uploading large packages of code, with at least a dozen dependancies.

Even in realworld cases the results of the changes in architechture were very similar, so please don’t think of it as yet-another-benchmark that the JVM isn’t handling properly yet.

I second Riven’s comment on the expensive Vec3 construction. I recently reworked some C++ code that used some vector math classes like the Vec3 class. All the Vec3 operators (±*/) allocated new Vec3 instances (stack allocation). Initially I converted this to ‘new Vec3()’ in the java code, but the performance was terrible. The algorithm in question was causing lots of very shortlived Vec3 instances to be allocated inside inner loops. I then reworked the code to reuse Vec3 instances as much as possible. This improved performance a lot, but the elegance of the code dropped :slight_smile: Unfortunately I can’t seem to find my test results…

Bad description on my part, but what I was trying to do was allude to the fact that a java object that merely contains a float also contains many other bytes imposed by the language. Whereas you have to re-initialize only the float with pooling, with new’ing you have to initialize a bunch of other data.

So, I took “object creation” as used in this discussion to mean “allocation + initialization of required JVM/language/platform data”.

No? Yes? Maybe?

Once again, it is probably the case that escape analysis and stack allocation will cure most of this. Due in Java 7 isn’t it? I’ve seen it working in Jet and it pretty much does the trick performance wise.

Cas :slight_smile:

Escape analysis will help and be a nice addition but it is no panacea. It should easily handle the trivial cases shown in typical microbenchmarks where an object is created, used once, and thrown away all within a single method. For harder cases, for example where the temporary object is used to marshal arguments for a possibly polymorphic method call, it remains to be seen how often escape analysis can handle this for real code in large projects. And of course, if the object has any significant lifespan, for example if the object is part of a larger object, then escape analysis cannot help. It does not allow objects to be inlined into other objects.

The small object overhead is still significant and while escape analysis is a good thing, it only fixes one aspect of a wider problem.

[quote]I read in some article* of a JVM engineer that creating new objects was ‘almost at the cost of shifting a pointer’.

  • I tried hard to find the article, but sometimes java.sun.com is kinda hard to wade through
    [/quote]
    I think CaptainJester just found the article you were talking about:

in this thread:

http://www.java-gaming.org/forums/index.php?topic=16512.msg130580;topicseen#msg130580

Thanks for backing up that statement.

It simply shows there is more to object-creation than just allocation. Even an object with an ‘empty’ constructor has significant overhead. At least the object-header has to be written (as it’s not a struct) which might require fetching the class-id, or something else entirely…

Object pooling in JOODE has speed it up by an order of magnitute.