Sign in to follow this  
Seer

Should anonymous inner classes be used in update?

Recommended Posts

In terms of efficiency, should anonymous inner classes be instantiated in update(), or any other function which is called every frame?

 

Here's an example, using setInputProcessor() from LibGDX

public void update()
{
    Gdx.input.setInputProcessor(new InputProcessor()
    {
        ...
    });
}

I ask because I'm not sure if "new InputProcessor()" is actually creating a new object each time update() is called, or if it is just done once, the first time update() is called. It might only be called once depending on whether instantiation of anonymous inner classes works differently. I couldn't find any information on this elsewhere.

 

If anonymous inner classes really are instantiated every frame like any other object when used in this manner, would you advise not using them in this manner?

 

Thanks.

Share this post


Link to post
Share on other sites

I ask because I'm not sure if "new InputProcessor()" is actually creating a new object each time update() is called
You're calling "new" and you're calling that method repeatedly. It is. Makes no sense to re-specify your input processor each frame.

 Lets see, https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/InputProcessor.java

 

Okay, its a plain interface.

That InputProcessor you're creating is an instance of an "annonymous" class that implements that interface. That instance can capture local variables and it captures a "this" reference of the owner object. So you're looking at 16 bytes or more for that object (12 bytes header, 4 bytes for parent 'this' reference, plus captured locals, on a 64 bit JVM).

Now, what gets allocated or not isn't actually that obvious in HotSpot (desktop JVM). For instance, look at this method from my framework:

https://github.com/dustContributor/dustArtemis/blob/master/src/com/artemis/EntitySystem.java#L125

That method gets called once per game tick, for every system. So you'd think that "new MutableBitIterator" would be created dozens of times per tick.

HotSpot has a neat thing called "escape analysis". After it does normal optimizations, like inlining, it can determine the scope of the object, and if the object doesn't "escapes" the scope (ie, passed to another non-inlined method, stored in a field/collection, passed to another thread, etc), it can eliminate its allocation and essentially only juggle with the fields it has.

In that particular case, after it has been executed enough times (second tier/C2 compile), HotSpot produces code that doesn't allocates that object in the heap. Thus that particular method becomes garbage free.

In short, unless you're sure what you're doing (used something like JitWatch to determine if the allocation is being made or not, and you know you're targeting HotSpot instead of Android/Dalvik/ART), try to keep those objects around.

Then again, retaining objects puts pressure on the GC, since it pushes objects to the old generation, which has more drastic and expensive collection algorithms. So its not always productive to keep objects around instead of re-creating them and letting the young gen GC do its thing.

Like with anything, there is a trade-off. In that particular case, I'd retain it in a final field or something.

Share this post


Link to post
Share on other sites

Thanks TheChubu.

 

Currently I would only be targeting the desktop. In this case, is HotSpot something I can rely on to optimize away such performance intensive code? The reason I might want to make the InputProcessor anonymous is because it would have simpler access to the members of the class using it. I thought it looked like a nice way to streamline using events for handling input.

 

Then again, retaining objects puts pressure on the GC, since it pushes objects to the old generation, which has more drastic and expensive collection algorithms. So its not always productive to keep objects around instead of re-creating them and letting the young gen GC do its thing.

Am I wrong then to try to allocate as much memory up front as possible? This is my current practice as I believed it saved the GC work. If so, how can you know when you should allocate up front and when you should allocate on the fly?

Share this post


Link to post
Share on other sites

The real question you have to ask is will the anonymous object close over any variables in Update(), if so you might not have any option. If you are not using closures to capture anything then TheChubu has covered the subtle impact of the different approaches you could take.

Share this post


Link to post
Share on other sites

In this case, is HotSpot something I can rely on to optimize away such performance intensive code?

Yup. Standard JVM in all desktops. It is OpenJDK's VM, the one you can download from any package manager in any Linux distro. Oracle grabs that, repackages it with a few tools of theirs (mission control thingy and some others), and calls it "OracleJDK" (or OracleJRE without the tools), which is the one you'd install in Windows or OSX.

Anyway, for actually checking if the magic happens or not, you should use JitWatch and inspect the VM logs. It allows you to see which methods get compiled, inlined, if escape analysis is working or not, it even lets you see the ASM generated by the JIT.

In that particular case of yours I doubt HotSpot can do escape analysis on the object since it probably gets stored in some internal libGDX structure, ie, it escapes the method's scope.
 

The reason I might want to make the InputProcessor anonymous is because it would have simpler access to the members of the class using it.

Of course, but its not completely necessary to do it inside your update function.
Just do it like:
 
private final InputProcessor inputProcessor = new InputProcessor() {
 @Override
 //Overriden methods.
};

// Then somewhere in an init function or something.
public void init() {
  Gdx.input.setInputProcessor(inputProcessor);
} 
Its not necessary for the anonymous class to be inside a normal method. You can create it from the constructor, or a field initializer.
 

Am I wrong then to try to allocate as much memory up front as possible?

Maybe, are you having issues with old gen collections taking a long time? This isn't something you can pin point by looking at 10 lines of code. It depends on how your whole program behaves.

You should try something like VisualVM and its various plugins. Visual GC plugin for instance tells you how many collections you're having, how much time are you spending in collections, etc. VisualVM alone can tell you how much memory your program is using, heap dump analyzer, and it has profiling/sampling tools. Tooling is one of Java's strengths, so there are plenty of (free!) tools to check around.

Anyway, desktop JVM is quite good at what it does, so you'd need to throw at it some serious garbage for it to become a problem. Say, Minecraft is what I would consider "serious garbage". Lots of volumetric structures and Notch not having a clue of what he was doing at the time.

Share this post


Link to post
Share on other sites

I tried what you suggested for the anonymous inner class TheChubu. It works well for one object, but when you have multiple objects that use an InputProcessor and respond to input mostly the same, like UI Buttons, only the last one that set the InputProcessor responds. I guess then a thing you could do would be to have a concrete InputProcessor class which holds a List of objects interested in responding to input and passing responsibility for handling the input events to them. Would that be a reasonable approach?

 

Maybe, are you having issues with old gen collections taking a long time?

No. I ask principally. Currently I'm not having any problems with the "allocate everything first, use later" approach. I just wanted to know if it was sub-optimal.

 

I find it can be difficult to know the right approach to a given problem. You'll often read conflicting arguments for and against doing such-and-such. Honestly though, this is the first time I've come across the notion that it's bad to try to stop the GC from doing work by pre-allocating.

Share this post


Link to post
Share on other sites

No.
Good then. Now if you start having those problems, you know what to look for.

Honestly though, this is the first time I've come across the notion that it's bad to try to stop the GC from doing work by pre-allocating.
I didn't say it was bad. I said it puts pressure on old gen collections, which might become an issue, depending on the behavior of your program. You might want to read the post again, you seem bent on this "this is bad, this is good" thing. Nothing is that simple.

Also have in mind there is a lot of out-dated Java advice out there. Nervermind all the Android specific things. In Android you'd pre-allocate as much as you can because Dalvik/ART sucks.

Would that be a reasonable approach?
I haven't used libGDX but you should read the docs https://github.com/libgdx/libgdx/wiki/Event-handling Specifically the section about InputMultiplexer, which seems to cover your specific case.

If you look at the examples, looks like you're supposed to set one InputProcessor that relays events to the interested parties,  or one InputMultiplexer with many processors inside, each doing their own thing (separating UI events from game events for instance, like in the example).

Honestly though, this is the first time I've come across the notion that it's bad to try to stop the GC from doing work by pre-allocating.
Then I take you haven't read about how GC is done in desktop JVM? You should. Otherwise you're cargo culting this, you're not really understanding why you should pre-allocate or you why you shouldn't. And again with the "this is bad, this is good" thing! The JVM is a complex thing with many moving parts, read about it, watch JVM architect talks, learn what it can and cannot do. Sometimes it can do really nifty things (like escape analysis, de-virtualization, intrinsics, etc), sometimes it can't, and you have to help it a bit.

For instance, I'll give you an example:

public Vec4f complexMath(Vec4f position, Mat4f transform) {
  // Big method that does complex math creating a few Vec4fs and Mat4fs inside.
  // And returns a new vec4 as result.
  return new Vec4f(resultX, resultY, resultZ, resultW);
} 

You might have a method that has a few vecs/mats as parameters, does complex math with vectors/matrices inside, and returns a vector. The method itself is too big for HotSpot to inline it (there is a configurable threshold for that), so while the mat/vecs created inside might get "escape-analyzed", the parameters and returned object wont be, because they "escape" the method.

Say that the method is called many times per frame (say, two or three times per entity, and you got one thousand entities). In this case you can introduce a "dest" vector parameter, where to store the results of that math, and you might store the method's parameter objects as fields in the calling object, so not to re-create them again and again when calling the method.

In this case you have two things: Pooling everything might not be totally productive, because if you pool the objects created inside the method you'll prevent escape analysis from working. And if you "new" everything, you will be creating tons of tiny objects per frame in the calling object.

See where I'm going? This is not absolute. You can eyeball some of this stuff but the only way to be sure is to check the VM logs (with JitWatch, which I linked before).

Share this post


Link to post
Share on other sites

And again with the "this is bad, this is good" thing!

Well, you did quote the same line twice :P

 

You're right though in that I don't have a great knowledge of how the JVM or GC work. For now I'll just keep doing as I am. If and when I do run into performance issues from pre-allocating too much, this is something I now know about and can look into further.

 

It's a bit of a shame about the anonymous class. Generally I've found the InputProcessor a little unintuitive to use. There can be some ambiguity as to where best to put it. In the past I've tried giving it to the object that needs it, not as an anonymous class but as a regular object. I don't think this is a good fit though. I have also put it in the class containing the main List of game objects and just constructed it with a relevant input handling object. Now the latest way has been as an anonymous class, but I have quickly discovered the limitations of that. It would be nice if I could use it this way in an objects update but it's too inefficient most probably.

 

The next way I can think of is to put it somewhere you can pass it a List of input handling objects on construction and then in each of its methods iterate through this List of objects, calling the relevant input handling methods on each of the objects. They would each have these methods through a common interface they all implement.

 

I have read that LibGDX article and many more, but it doesn't go into great detail as to how the InputProcessor can be used, or if it should be used in the way I'm thinking of. Regarding this, even though you haven't used LibGDX, from your experience might this be a reasonable approach to processing input events across multiple objects? If not can you suggest another possible way?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this