Productivity Versus Performance: Fighting The Good Fight

If you've been following the Javascript MVC landscape lately, you might have noticed a growing tension between Backbone.js and Ember.js. Being championed by Jeremy Ashkenas and Yehuda Katz respectively, both frameworks reside in decidely different camps. Ember.js favors deep abstraction and sensible defaults, whereas Backbone.js embraces the micro-framework mentality of providing a minimalist set of features whilst encouraging integration with a wide variety of other frameworks.

The most recent evolution of the debate, however, has resided around performance. An animation benchmark comparing the two frameworks was posted on Hacker News yesterday. Despite being a contrived example, the results of the benchmark are undisputable: Backbone.js is significantly faster than Ember.js - and by a visible margin. The reason for this is the computational overhead incurred by Ember's view binding system. A core feature of Ember is a rich, bindable and composable view system which has been designed to simplify common programming tasks. Simply put: Ember.js has been built to make development easier.

Of course Ember.js could be optimized and the gap in the benchmark could be narrowed, but that is moot. What is really happening here is the age old dispute of developer productivity versus application performance. New technologies are constantly being introduced which make the lives of developers easier and encumbent technologies will always defend their trenches. The easiest thing for existing technologies to point at is performance - as grander abstractions naturally incur larger overheads. These might be a little more stark than the Ember vs. Backbone debate, but here are some examples that immediately come to mind:

  1. Assemby vs. C: When I was younger, our family computer had a great operating system installed called GEOS). It was a really nice piece of software. Only later in life did I learn that it was written almost entirely in 8086 assembly language. Despite being written in the ultimate low-level language, it ultimately became a slower product than its competitors and part of its demise was due to system complexity.

  2. Java vs. C++: When Java was first introduced, it was ridiculed for being extremely slow. Over time, especially in the post-JIT era, it has gained the opposite reputation. In today's landscape, the JVM is considered one of the faster platform choices, even exceeding C++ in some benchmarks.

  3. Static vs Dynamic: Among other things, dynamic language skeptics have always pointed a finger at performance. Even today, lanuages like Ruby and Python are still an order of magnitude slower than some of their static counterparts. Despite this, frameworks like ROR and Django are industry norms. Javascript itself has also defied people's beliefs and expectations as projects like V8 have taken it to the next level.

There are two things going on here:

The first is summarized succintly by Steve Yegge: "Global optimizations always trump benchmarks." Even if a framework/language is slower at a granular level, a system with an overall reduced complexity will still run faster. I would much rather live a world where I can do more faster while at the same time benefitting from global optimizations introduced transparently by the framework itself than one where I consciously chose to sacrifice convenience for performance.

Second, slow is relative. It is important to know when performance matters and when it doesn't. Databases, real-time systems, and heavily trafficked servers clearly benefit from saved cycles. Apparently it makes sense for CouchDB to move to C/C++ from Erlang, but there are also a lot of situations where performance just simply doesn't matter that much.

The realm of client-side development is a perfect example of this. Where else do you have essentially unbounded access to a modern CPU in order to scale an application to all of a single user? If anything, in most cases there is a glut of CPU resources that are under-utilized. In the case where you absolutely need to ensure a complex animation runs smoothly, any good framework will allow you to break away from its shackles and apply some manual optimization (you should probably be exploring something like WebGL in this case anyways). There are very few reasons to prematurely optimize for performance in client-side web developement.

In all fairness, Ember.js still does have work do to in the performance area and is actively being developed. Backbone.js is also a great framework and a good choice for a number of applications. At the end of the day, however, to fundamentally criticize a javascript framework for being slow is really to suggest that we have reached the limits of front-end web development. I sincerely hope that is not the case. We should all be striving as developers to make our lives as easy as possible. I personally hope that Ember is just the tip of an iceberg and that even more feature-rich, abstracted, and \gasp** possibly slower frameworks are on the horizon.

comments powered by Disqus