I ask in terms of high cost classes, with a particle engine as an example.
I read somewhere that an instance of a class with a high cost to initialize, like a particle manager, should have its state variables altered at run time rather than reinitialize the particle manager with new data every time it is used in a different way.
The particle manager would create perhaps thousands of instances of particles on initialization and then manage them from then on.
For example, let’s say this particle manager is used to manage shrapnel in an explosion; and you’re creating a ground zero simulation for an artillery attack; thus there are many explosions.
Instead of multiple managers for each explosion, which is extremely expensive, you alter the variables for each explosion and have a scattered sequential set of explosions using the same manager and the same particles.
So I ask: is it fine to reuse a class instance at run time? Or is the above really just a super optimization case?
3
It is perfectly fine to reuse an object like this as long as it is written correctly for that purpose.
Invoking behavior on the object should not be affected by any previous calls to the object. Consider the following code:
class Example {
private int x = 1;
public int multiply(int y) {
return x *= y;
}
}
Calling the multiply()
function alters the state of the class. Calling it multiple times produces different results, so to produce consistent results you would need multiple objects. Granted this is a contrived example but it shows the issue: this class is not easily reusable by two different processes.
It may also be permissable to have a way to reset an object. Perhaps it has complex storage requirements, and it is faster to zero out its storage than to release and reacquire resources. This is a simple Java example showing what I mean:
List<Object> data = new ArrayList<Object>(1000000);
someMethod(data);
data.clear();
someMethod2(data);
While ArrayList
is not a really expensive object, think about a million element array. Perhaps it is faster to zero it out than to ask the memory manager to find another chunk of memory that can accommodate that much storage (and Java will zero out the memory anyway, making clear()
work faster in this case).
Unfortunately there is no way to say for sure that it will or will not always work, all we can do is say “if the code does this, it will or will not work.”
1
Assuming the previous usage is completed and no paralelism takes place:
It depends on cost (both runtime and developement) of getting the instance into “neutral” state. Sometimes its easier to delete (or not reference it anymore and leave releasing for GC) whole object than inspect and delete its parts. And sometimes it’s hard to be sure you did it right.
And sometimes original author did not exepect reuse, so some operations are one way only.
And reusing object can (in systems with GC) lead to it being moved to longer lived generation, so even if it is not needed soon after it will be GCed much later (if it is needed then it does not matter).
That does not mean you should never do it, just think about consequences and measure result.
If you are designing such object, try to split it in expensive reusable object (not containing state from usage) and as cheap as possible nonreusable usage specific object. (eg. in hibernate there is Session factory (expensive) and it creates session (relatively cheap).