Improving JPSpan Performance with an Object Pool

Some people commented in my AJAX Hello World with JPSpan article that the JPSpan example app was quite a bit slower. After a bit of testing it does seem that the performance problems comes from each JPSpan object having only 1 XMLHttpRequest object, this means if you use 1 object you can only have 1 outstanding call.

I would like to see this fixed with an pool of XMLHttpRequest objects at the JPSpan level, however im sure this will take some time so I have a solution for you today.

Its a small javascript class that implements a simple autogrowing object pool for the create JPSpan remoting objects. I’ve created an updated version of the JPSpan Hello World app that uses the pool and it seems much faster to me.

To use the pool you just need to include objectPool.js.

Then you just need to setup your pool. You’ll notice that the callback object recieves a reference to its parent remote object, this will be used to return the remote object back to the pool.

var remotePool = new objectPool();
// Overwrite the createObject method on the pool so that it will create a new helloworld object with a new callback
// note the lowercase mapping on the helloWorld php class
remotePool.createObject = function() { var cb = new hwCallback(); var remote = new helloworld(cb); cb.remote = remote; return remote; }

When you make a remote call now just get the get the object from the pool first.

function setup() {
                var remoteHW = remotePool.getObject();

Then in the callback when your in the callback method you return the object to the pool. Note that you just pass back a poolId that is set on the object not the entire Object.

hwCallback.prototype.stringcount = function(result) {
                document.getElementById('count').innerHTML = result;

Thats it your JPSpan apps are now a lot more responsive (of course this means your hitting the server a lot more).

Full source of updated JPSpan HelloWorld app, Try updated JPSpan HelloWorld app, try old JPSpan HelloWorld app.

Couple notes on the Object Pool.

Its pretty simplistic right now there are a couple things im going to update.

  1. Allow returnObject to take an object back just to make things more fool proof
  2. Add in the ability to limit the pool size and various options if that happens, either performing a function on current objects to recover them or just sleeping for a bit
  3. Adding some maintenance methods to let you get specific objects from the pool

Im also going to investigate a couple things but im not sure if its worth it.

  1. Allowing a pool to contain more then 1 type of object
  2. Adding in a method that checks if the object is ready to be returned to the pool instead of returning them with returnObject

If you think you’ll use this code or have any feedback on the items above let me know.

9 thoughts on “Improving JPSpan Performance with an Object Pool”

  1. “I would like to see this fixed with an pool of XMLHttpRequest objects at the JPSpan level, however im sure this will take some time so I have a solution for you today.”

    Got two minds about this. On the one hand – agree – this is something someone using JPSpan should, ideally, not have to care about and as I’m saying JPSpan is about making life easy, it should do just that.

    On the other I’m not yet convinced it can be handled transparently in JPSpan without resulting in stranges bugs, and so “forcing” this onto the user means that the best decision will be made for their specific requirements. I really need to do some more testing to nail this stuff down exactly but here’s some of the issues;

    – Using an XMLHttpRequest object that is already making an async request DOES result in wierdness. Exactly what kind of wierdness I can’t say exactly – had some strange experiences while working on the earlier parts of JPSpan but was able to narrow it down well enough thanks to other bugs and issues I was dealing with at that time.

    – Creating more than “X” XMLHttpRequest objects and having them all make async requests at the same time _may_ also lead to wierdness. Andreas Halter ( tipped me off about this. He’s done a fair deal with XUL and mentioned he’d run into a problem where when you have more than, say, 10 requests in progress at the same time, the responses start getting mixed and you might get the response from one request coming back via a seperate object. I haven’t been able to reproduce this myself but it makes me nervous.

    – What are the memory / object setup costs here? Is it better to have a pool of objects ready to serve requests (as is done in libXMLRequest) reducing the perceived performance overhead once the page is loaded, at the cost of memory and extra code to manage the pool. Or is it better to simply create a new object when needed?

    Anyway – going to experiment further in this direction and see how it goes.

  2. Link is fixed.

    I’m not sure what the solution memory wise is, im just creating more proxied objects so a pool seemed the way to go for that since the object might be quite large.

    At just the XMLHTTPRequest level the overhead wouldn’t be quite so large but maybe a pool still makes sense since you’ll want the ability to limit the # of outstanding requests, both to limit server load and to keep the browser for having “weird” problems.

  3. Hi,

    the helloworld demo produces an ” [Client_Error] [413] Request Entity Too Large while calling helloworld.randomstring()” but works fine with Firefox.

    Do you know why?

  4. I forgot to mention: “…it works fine with firefox but not with _Konqueror_.”
    I tested with Konqueror 3.4 (Ubuntu 5.04).

  5. Well I have no clue what Konqueror supports I would guess it doesn’t have a full XmlHttpRequest implementation, if you know of any docs let me know and i’ll take a look.

  6. Pingback: BrianJava » AJAX FAQ for the Java Developer

  7. Pingback: AJAX FAQ « IT FAQ for Students – Roy Antony Arnold G

Comments are closed.