jLinq Reloaded

My first 'open source' project I ever released was a Javascript library that allowed you perform LINQ style queries with arrays of objects. The library supported operators, extension methods and even memorized commands to reduce typing.

Overall, it did a good job of making it easier to select information that normally would need to be handled with a for loop. Unfortunately, it turns out jLinq is rather slow. I recently blogged about a performance evaluation that came back with less than flattering results.

However, this is exactly where 'open source' helps make better software. If I hadn't released my code then I might never know how it could be improved. This is the sort of thing that inspires software developers to improve their code -- and that is exactly what is did for me.

So for the past few days I've been completely rewriting jLinq from the ground up and the gains have been incredible to say the least.

  1. About 60% smaller (around 8kb compressed)
  2. 99% faster queries
  3. Easier to extend library
  4. Minty fresh scent (your results may vary)

There has been a lot of interest already in seeing the new code so I've started a new repository on github.com. This is beta code so I suspect I'll have errors in it. Please feel free to contact me to log an issue on the site.

If you're interested in how jLinq improved so much then read on...

jLinq... But On Caffeine

My first theory about why jLinq was so slow had to do with the use of evals in my code.

At the time, I didn't understand you could pass functions as arguments, I certainly had no idea what enclosures were, so jLinq would build an entire query in a string and then eval it into a method that could be invoked against each record.

I also used eval to get values from records instead of just referring to them by their names as an index. I don't know why eval is so much slower, but the difference is undeniable.

//using index names
var fast = function(obj, path) {
    path = (path+"").split(/\./g);
    var index = 0;
    while(obj != null && index < path.length) {
        obj = obj[path[index++]];
    }
    return obj;
};

//being lazy with an eval
var slow = function(obj, path) {
    return eval("obj."+path);
};

//looping 100,000 times
loop(100000, function() { fast(data, "name.first"); }); //128ms
loop(100000, function() { slow(data, "name.first"); }); //6.8 minutes

So what kind of improvement do these two changes result in? Big ones.

Type

Previous

Current

Single Argument Query

~430ms

~10ms

Multiple Argument Query

~2730ms

~35ms

Simple Join

~6200ms

~135ms

The list of improvements goes on but I'll talk about them more in later blog posts.

So What Is Next?

It's screaming fast and much smaller but unfortunately it is too new to even suggest that it is put into production. I'll definitely feel more confident in the code after I've finished the tests.

But I also plan to rebrand the library this time. Why?

As it turns out, the name LINQ has caused some confusion with non-.NET developers. I've heard that some developers see the name and say 'Well, I don't use .NET so I don't need this.', which is clearly not the response I'd like to hear.

jLinq isn't only for web pages. In fact, the neat thing about jLinq is that it can be plugged into anything running Javascript and it works great. I'd like to see jLinq be exposed to more developers.

So, with a new name, new site and all brand new code I think there is a chance to redefine what jLinq can do for the community.

The code is mostly finished so now it's time for the hard part... coming up with a good name...

August 8, 2010

jLinq Reloaded

Post titled "jLinq Reloaded"