Swapping Endian-ness in JavaScript

09 Aug 2007

My mentor came up with two interesting ways of swapping endian-ness on JavaScript. The first one he proposed was based on what was “usually done in Plan 9”, something along the lines of:

b = "\1\1\1\2";
n = (b.charCodeAt(0) & 0xff) << 24;
n += (b.charCodeAt(1) & 0xff) << 16;
n += (b.charCodeAt(2) & 0xff) << 8;
n += (b.charCodeAt(3) & 0xff);

which gives us n = 16843010.

Maht then had a look at the series of JavaScript lectures by Douglas Crockford at Yahoo!. The first of the series tells us that bit shifting is not faster than simple multiplication. Maht gave me this code snippet doing the same conversion, but using multiplication instead of bit shifts this time:

b = "\1\1\1\2";
n = b.charCodeAt(0) * 16777216;
n += b.charCodeAt(1) * 65536;
n += b.charCodeAt(2) * 256;
n += b.charCodeAt(3) * 1;

n, is of course 16843010; the real question is how much longer (or, shorter) did this take.

Venkman is probably one of the more mature “old-school” JavaScript debuggers out there. FireBug, the relatively modern sibling to Venkman certainly has a few nifty features, but profiling is not one of its strong points. After failing to profile the script in FireBug, I used the trusty old Venkman - and it came up with some interesting results:

Venkman Profile Report
Created ………. Thu Aug 09 2007 20:18:54 GMT+0530 (IST)
User Agent ……. Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv: Gecko/20070725 Firefox/
Debugger Version . Venkman 0.9.87 [Mozilla rv:]
Function Name: multi (Lines 1 - 6)
Total Calls: 1 (max recurse 0)
Total Time: 0.21 (min/max/avg 0.21/0.21/0.21)
Time (ex. calls): 0.21 (min/max/avg 0.21/0.21/0.21)
Function Name: shift (Lines 8 - 13)
Total Calls: 1 (max recurse 0)
Total Time: 0.02 (min/max/avg 0.02/0.02/0.02)
Time (ex. calls): 0.02 (min/max/avg 0.02/0.02/0.02)

As you can tell from the function names, multi uses simple multiplication, while shift uses bit-shifting. Turns out that bit-shifting does indeed take a lot lesser time. A Firefox quirk?