1

I am creating a java program which will have to deal with a LOT of Points. When I say a lot, I am talking about upwards of 100,000 Points. Furthermore, I will have to be creating points over and over again. I am worried that this object creation will slow down my algorithm time, and use up big chunks of memory.

I have come up with few possible solutions, would these work? Are there better ways to handle the situation?

Solution 1) -A Point "Factory", where all points are sent to instead of being destroyed. Here, they will be recycled so we do not have to re-create an object.

public class PointFactory {

public final static List<Point> unused = new ArrayList<Point>();


public static void disposePoint( Point point ){
    unused.add( point );

}

public static void disposePoints( List<Point> points ){

    for( Point point: points )
        unused.add( point );

}


public static Point newPoint( int x, int y ){

    if( unused.isEmpty() )
        return new Point( x, y );
    else{

        Point point = unused.get(0);

        point.x = x;
        point.y = y;

        return point;

    }

}

}

Solution 2) Very similar to solution 1, but uses a new structure "XY", to avoid un needed overhead. All I need are X and Y values.

public class XYFactory {

public final static List<XY> unused = new ArrayList<XY>();



public static void disposeXY( XY xy ){
    unused.add( xy );

}

public static XY newXY( int x, int y ){

    if( unused.isEmpty() )
        return new XY( x, y );
    else{

        XY xy = unused.get(0);

        xy.x = x;
        xy.y = y;

        return xy;

    }

}

}

public class XY {

public XY( int x, int y ){
    this.x = x;
    this.y = y;

}

public int x;
public int y;

public boolean equals( Object o ){

    if( !( o instanceof XY ) )
        return false;

    XY xy = (XY)o;

    return xy.x == x && xy.y == y;

}

}

  • 1
    You've forgot to remove the point from the list of unused points in `public static Point newPoint`. Also, you're better off with stack instead of array. – Vlad Aug 21 '12 at 22:14

6 Answers6

2

I would be surprised if the time it takes to construct an object with merely two ints was taking a toll on your application. I would bet that the overhead of maintaining an object pool or a factory as you have implemented incurs a similar overhead but this would need to be profiled. But if you find this to be an issue look at constructing an Object Pool

Ian Dallas
  • 12,451
  • 19
  • 58
  • 82
2

This sounds like a premature optimization. If, when you actually implement your algorithm, you notice a significant performance decrease because of object creation, then you should start thinking about things like this, not before.

Each instance of java.awt.Point will take up ~16 bytes of memory:

  • int x = 4 bytes
  • int y = 4 bytes
  • Object overhead = 8 bytes

100,000 Points = 1,600,000 bytes = 1.52 MB

Jeffrey
  • 44,417
  • 8
  • 90
  • 141
2

Just to be clear. This is not my personal opinion, it is from Brian Goetz (Bloch, Lea etc) from Java Concurrency In Practice

The recomendation is Don't do object pooling.

According to these experts: The allocation of objects is significantly faster than ever before in recent JVM editions, and pooling has been shown actually to degrade performance (except in very specific cases e.g. database pooling) for various reasons e.g. too big pool affects the GC in a bad way, but too small offers nothing, subtle bugs when an object is not properly returned to the pool etc. worse performance in multithreaded applications since by not instantiating new objects and reusing cached ones, someone has to block etc.
Before reading about this, I always thought that the recommended approach is to use object pools.
Turns out after reading the book that it is in fact an anti-pattern (if not used for indeed-proven expensive objects).
So just allocate your objects as needed using plain old new and if your object allocation is indeed proven to be expensive (by profiling etc) then start looking into pooling and caching strategies.

The recommendation by @Jeffrey IMHO shows a nice approach to start investigating if your objects are really expensive. It's a starting point.

Cratylus
  • 52,998
  • 69
  • 209
  • 339
1

I've done lots of projects dealing with millions of objects, instancing objects was never the main performance problem.

As soon as you make IOs, like reading from a Database or reading a file, creating new objets will look like very very fast.

joel1di1
  • 773
  • 5
  • 13
  • It is generally not a main performance issue, but it can affect latency. Low latency programming is not typically a need; but for some projects it is a base requirement. The Disruptor pattern is what comes to mind. – Edwin Buck Aug 21 '12 at 22:22
1

The XY structure is actually just a clever renaming of the data members of your point. It won't buy you anything extra, beyond putting the data in the wrong class (and creating a second class for overhead).

The factory method, by contrast will save you the need to allocate duplicate points (like 0,0) if you have already allocated them. You could cache the points and return the same point from the cache if you get subsequent requests for 0,0.

Depending on how you structure your factory, you might even be able to reclaim your points and "recycle them", meaning "reset their x and y coordinates, returning the same object in a second "use". However, such techniques are generally frowned upon, as if you don't have a means of verifying that a point is unreachable before you reset the X and Y values, you typically introduce unwanted behavior into your program.

In any case, I would not advise making the points "updateable" after the factory releases them; because, if they are, then the entire ability to wrap the point identity management within the factory class becomes so complex it is probably not worth it.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
0

You seem to be approximately reinventing the Object Pool, which is perfectly reasonable should you actually need it.

But you should probably read up on this pattern and name it appropriately if you use it. "Factory" is used for too many things already.

Don Roby
  • 40,677
  • 6
  • 91
  • 113