----- "Gilles Sadowski" <gil...@harfang.homelinux.org> a écrit :

> Hello.

Hi Gilles,

> 
> Would you consider implementing a _mutable_ 3D-vector class?
> A crude benchmark which I just did shows that re-using the same object
> is
> always (if sometimes only slightly) more efficient than re-creating
> it.

3D vectors have been changed from mutable to immutable for both robustness and 
efficiency reasons ...

When small benchmarks are set up, the overall context is completely under 
control and instances are created/used/reused in a specific use case, 
corresponding to a simplified view. In these cases, instances modification 
appear faster and manageable.

Real life situations with complex systems are not that simple.

Here is a summary of a real case problem, encountered on an operational library 
using commons-math and Vector3D before it was turned to immutable. In a complex 
application with lots of data sharing and time-dependent data, we wrote 
something like:

  Vector3D computeMotion(Trajectory trajectory) {
    Vector3D initialPosition = trajectory.getCurrentPosition();
    complexAlgorithm.processTrajectory(trajectory, targetDate);
    Vector3D finalPosition   = trajectory.getCurrentPosition();
    return finalPosition.subtract(initialPosition);
  }

The team developing computeMotion and the team developing Trajectory worked 
apart from one another.

With mutable vector, you must be sure the two teams are aware that at each 
interface they must really know who is responsible for the data, the caller or 
the callee. They may decide that getCurrentPosition should build and return a 
new vector, which belongs to the caller which can do what it wants with it, 
including modifying it. In this case, two vectors are built since getPosition 
is called twice and processTrajectory has no implementation constraint. They 
may decide that the getCurrentPosition should return a reference to an internal 
vector, then computeMotion should be rewritten to clone initialPosition before 
finalPosition is retrieved. They should also know if the clone must be created 
before or after the processTrajectory call because the internal reference may 
be modified internally. Failing to have a very precise interface definition 
which includes the responsibilities at each level leads to difficult to find 
bugs.

In order to avoid these bugs, you often resort in using defensive programming 
and adding a copy yourself, just in case the other team did not do its job 
properly. In some case, when what you develop is by itself an intermediate 
library and you don't know how the instances you create will be used, you 
*must* do this copy.

This leads to a strange result: you have a potentially buggy code if one of the 
team forgot to do defensive programming properly and you have a code that is 
really inefficient just because everybody copies everything even when in fact 
it is not needed.

With immutable object, on the other hand, you really don't have to worry at 
all. People cannot change the object whatever they do, so you just keep 
references around and create new instances when you want to change one 
coordinates. You cannot do otherwise and don't rely on programming rules or 
developers being smart. There are much fewer bugs and since new instances are 
created only when needed, at the end you have not that much allocations.Here is 
a good article about immutable objects: 
<http://www.ibm.com/developerworks/java/library/j-jtp02183.html>

At the end, it appears that for complex applications with several layers, there 
are more copies and allocations with mutable objects than with immutable 
objects!

Another point to note is that the generational garbage collectors work better 
with really short lived objects. So small immutable instances are handled 
quickly and allocation should not be feared. It is efficient now, see 
<http://www.ibm.com/developerworks/java/library/j-jtp09275.html>.

The points above are not theoretical one. Vector3D was mutable and it cost us 
weeks of works at that time to track difficult bugs in a complex application. 
This was not a simple problem of communication: I was involved in all teams 
from commons-math to high level application, the rest of the team was just 
around me and we exchanged lots of information. After we changed to immutable, 
all problems were gone and we didn't notice any performance drawback. In fact, 
another team in another project facing huge performances problems looked at 
what we have done and changed also their objects to immutable: they got 
significant performance improvements after that change because their code was 
copying everything beforehand and it was not needed anymore afterward.

Luc

> 
> [I can help with the editing work.]
> 
> Best,
> Gilles
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
> For additional commands, e-mail: dev-h...@commons.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to