2
\$\begingroup\$

Assume the server is sending data to our app at regular intervals, at least once per second. The received data is parsed and stored in memory as a POJO. A blocking queue is processing data in a worker thread.

Suppose I want to use a very simple object pool, so I don’t have to create a new POJO for each server response. I don’t want to use e.g. Apache Commons Pool.

Would the following implementation suffice?

public abstract class ObjectPool<T> {

    private final Stack<T> mPool;

    public ObjectPool() {
        mPool = new Stack<T>();
    }

    public T obtain() {
        if (mPool.isEmpty()) {
            return create();
        } else {
            return mPool.pop();
        }
    }

    public void recycle(T object) {
        if (null != object) {
            destroy(object);
            mPool.push(object);
        }
    }

    public void clear() {
        mPool.clear();
    }

    public int getSize() {
        return mPool.size();
    }

    protected abstract T create();

    protected abstract void destroy(T object);

}

Can I shoot myself in the foot using this? Any caveats I’m not seeing?

Thanks!

\$\endgroup\$
3
\$\begingroup\$

I have to question whether this makes any sense in your application:

Assume the server is sending data to our app at regular intervals, at least once per second

Have you done any testing/metrics that indicate that the current system you have is actually a problem? I would be very surprised if it is.

If the server is sending data as infrequently as that, there does not seem to be any reason to 'pool' the objects at all. The overhead of 'cleaning' an instance, storing it, recycling it, repopulating it, and repeating with it is probably just as overwhelming as simply creating a new instance and GC'ing the old one.

Unless you can already identify 'specifically' that object creation is a significant part of an existing performance problem, I would suggest that you are looking in the wrong places for performance improvements.

EDIT - hypothetically...

Answering hypothetically: no, I don't believe your solution is enough...

  • by the time you get to the frequency where object creation/reuse is a problem, you will be needing multiple concurrent threads to do the work anyway, and your solution is not synchronized (by the way, new and GarbageCollection are thread-safe)
  • You have created an artificial latency in your program flow - see Ahmdahl's law .. by adding to the critical path instead of taking work off the path (parallelizing things). As your system gets busier, you are making the problem worse and not better.

Bottom line, is that, at low volumes your current solution is not going to make a difference, and that at high frequencies, your solution is only going to make things worse.

One other thing to consider, and Android performance is not my strength, but on 'full' computers (I often work with systems with more than 128 cores in highly-threaded systems), the cost of having to bring the stack in to your system cache, and then replace it with the cache of your object is probably going to be more than just creating a new object would... Again, the more busy your system, the more this sort of issue 'hurts'.

\$\endgroup\$
  • \$\begingroup\$ You are right - brief tests show the current system is performing OK. The reason I’m asking is because the frequency could pick up at any time, growing at a polynomial rate. With older devices we support, this might be a problem. For the sake of argument, let’s assume pooling would be required. Would my implementation be enough? \$\endgroup\$ – Tadej Dec 10 '13 at 14:54
  • \$\begingroup\$ @curtisLoew - added an edit. \$\endgroup\$ – rolfl Dec 10 '13 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.