Thu 29 Mar 2007
If ever a feature of JavaScript was considered harmful, it’s eval(). It’s so commonly abused that if I’m interviewing a JS web developer, I usually ask something along the lines of “what is eval(), and why shouldn’t you use it”. It’s so commonly abused that Yahoo JavaScript architect Douglas Cronkford considers it “evil”, and his JavaScript style checker JSLint reports use of it as an error.
Specifically, he says:
The
evalfunction (and its relatives,Function,setTimeout, andsetInterval) provide access to the JavaScript compiler. This is sometimes useful for parsing JSON text, but in virtually all other cases it indicates the presences of extremely bad coding. Theevalfunction is the most misused feature of JavaScript.
Well I’m tired of my favourite function being badmouthed just because some people can’t program properly. In this article I show how to use eval to generate optimised code based on information only available at run time. The resulting code is 5 times faster than the non-generated version.
March 31st, 2007 at 3:25 pm
Good article, Bernie. I had run across Doug’s comments about eval on his jslint page, and considered them for a while, but there are some things you just have to use it for. It’s in the language for a reason, and the language wasn’t invented by dummies (even though it’s a bit quirky and they probably made a few mistakes in its definition). To declare eval evil because bad programmers use it badly, you’d also have to declare that looping is evil because bad programmers use it badly… etc.
It’s good to see you paying attention to performance issues in Javascript. IMO, too little attention is given to that subject, but in Javascript, it’s even more important to pay careful attention to that stuff. I’ve been thinking about some subjects for a “High Performance Javascript” article. Stuff like: a.b[i].c.d.f{’name’} is slow (and dangerous). Cache a.b[i].c.d.f if you’re going to access that object than once… just how slow is b[i]… how slow is string concatentation… performance characteristics of regular expressions… blah, blah…
April 1st, 2007 at 2:35 pm
You’re right, performance in JS is overlooked, perhaps because developers tend to have fast machines (and also because slow code makes their user’s computers crawl, not the server: it might be slow but the slowness in infinitely scalable :o)
A couple of links to articles about optimisation:
I think there’s scope for an up to date compendium of tips. What would the ideal format be, a wiki?
April 4th, 2007 at 2:09 am
Hmmm, a wiki would be a really good way to accumulate the info… benchmarks, tips and techniques, code samples, etc….
April 4th, 2007 at 8:57 am
It would need to be a custom wiki, because there’s structure. It would be a shame to rely on people e.g. putting a box in the top left corner of each page with the tip summary (as in the first link in my last post). I think TWiki would let you create forms so each page looks similar.
Perhaps people could submit code fragments in a certain way, and the fragment would get tested using some standard timing widget.
Interesting. If only I didn’t need sleep!
April 5th, 2007 at 3:39 am
I’m sure I ran across a timing widget at one point… firebug has a profiler that might be useful, but not necessarily in some automated fashion. How hard could it be to write one?
Ahhhh yes… sleep… I sort of remember what that’s like…
April 7th, 2007 at 3:46 pm
Here’s one attempt at benchmarking various Javascript primitives… http://www.jorendorff.com/articles/javascript/speed-test.html
April 9th, 2007 at 11:07 am
That’s perfect because the tests are posted as HTML, and run automatically.
Now imagine anyone coming to that page, running the tests, and the results being posted back to the server for collating.
You’d run it on a domain with no cookies or login, so there’s nothing for the scripts to steal if someone posts malicious code.
April 12th, 2007 at 12:43 pm
It would be challenging to account for the variables, like cpu speed, memory size, etc. Easier to account for the browser being used… But if you got enough people to do it, in the end statistics would win out and you could derive a statistically valid cost of specific operations… in the end you wouldn’t be able to say “this is the cost to YOU for this operation,” but you -would- be able to say “this is the relative cost of these two operations, and if you use the faster of the two, on average your site will perform better for all visitors.” THAT would be cool, and in fact much more valuable…
April 12th, 2007 at 1:16 pm
Indeed. If the data set is large enough, one could present standard deviations, or some more user friendly measure of variance, to indicate if an operation is generally fast but seems to really kill some browsers / configurations.
I had another look at TWiki, it looks suitable for creating a site where people can submit code into a standard test suite, but not suitable for collecting the results from visitors. We’d probably need a custom web app for that.
I am looking for an excuse to learn Ruby on Rails, but there’s so little time…
The next big block of time I have free is my Honeymoon in 3 months, and I’d be dead for even suggesting that I bring the laptop ;o)
April 14th, 2007 at 3:20 pm
Awww go ahead and sneak the laptop into the luggage… you gotta have somewhere to download the digital pics, you know… ;)
July 21st, 2007 at 8:05 am
I’ve written a very compact client-side HTML generation library (under 4k)… and it very heavily relies upon a single eval() statement to define hundreds of functions named after the HTML tag/attributes that they implement. It is very fast, and in benchmark tests, it beats both DOM and innerHTML methods of creating large constructs. In the website referenced, I’ve provided an online HTML() Construction Kit tool that allows you see how clientlets get rendered.
In the example, the 115 byte expression…
[[o=’O',x=’X',o].TD(),[x,x,x].TD(STYLE(background_color(’red’))),[x,o,o].TD()].TR().TABLE(BORDER(1)+CELLPADDING(5))
…renders 255 bytes of flawless HTML…
<table border="1" cellpadding="5"><tr><td>O</td><td>X</td><td>O</td></tr><tr><td style=" background-color: red;">X</td><td style=" background-color: red;">X</td><td style=" background-color: red;">X</td></tr><tr><td>X</td><td>O</td><td>O</td></tr></table>
In fact, this library is the basis of a pop-up calendar (a date selector) implemented in well under 5k.