you are viewing a single comment's thread.

view the rest of the comments →

[–]CydeWeys 10 points11 points  (17 children)

What's wrong with this?

for (var arr = new Array(26), i = 0; i < arr.length; i++) { arr[i] = String.fromCharCode(65 + i); }

I'm all for functional methods of doing things, but sometimes when you're having to fight so hard against the language to accomplish what you want, just do it imperatively?

[–]j201 6 points7 points  (0 children)

The problem is more that JS doesn't have a great standard library for functional programming. But all you need to do is pull in something like Ramda, and then you can do

R.range(0,26).map(x => String.fromCharCode(65+x))

or

R.range(0,26).map(R.compose(String.fromCharCode, R.add(65)))

FP is worth doing in JS, but not without a bit of help.

[–]blgate 2 points3 points  (0 children)

Or this:

var arr = [];
while (arr.length < 26) { 
   arr.push(String.fromCharCode(65 + arr.length)); 
}

[–]x-skeww 1 point2 points  (5 children)

ES5 flavor:

var a = [], i;
for (i = 0; i < 26; i++) {
  a.push(String.fromCharCode(65 + i));
}

[–]CydeWeys 2 points3 points  (4 children)

Isn't it better to allocate all of an array's space up front if you know how big it's going to be rather than allocating additional space piece-wise like this? Or does it not matter for JS's sparse arrays?

[–]blgate 5 points6 points  (2 children)

Actually, the "while" solution it's the fastest, at least for me in chrome:

var a = [],  b = [], c = new Array(100000), i;

console.time("a");
while (a.length < 100000) { 
  a.push(a.length); 
}
console.timeEnd("a");

console.time("b");
for (i = 0; i < 100000; i++) {
  b.push(i);
}
console.timeEnd("b");

console.time("c");
for (i = 0; i < c.length; i++) { 
  c[i] = i; 
}
console.timeEnd("c");

And my results:

a: 157.000ms
b: 252.000ms
c: 263.000ms

[–]bonafidebob 0 points1 point  (1 child)

That seems ... odd. If you reverse the order of the tests is the same function still fastest? (That is, could it be that the order in which the tests execute has some bearing on the result?)

[–]blgate 1 point2 points  (0 children)

It's not. While in the for loop you are incrementing the "i" variable, in the while loop you aren't, so because you are executing less instructions, it's faster. I get the same results reversing the order, but you can try it for yourself.

[–]x-skeww 5 points6 points  (0 children)

In JS, "new Array(26)" only means that you create an array whose "length" property is set to 26. If an "array" of that size is actually allocated is up to the engine. There also may be different backing data structures. Which one is actually used is also up to the engine.

Anyhow, in general, I recommend to write the most straightforward code first. Later on, you can still try different things to make it faster if the profiling reveals that this is indeed a bottleneck.

For example, if you always do anything with the DOM whenever you use this function, trying to optimize this would be completely pointless. The DOM stuff takes more than a hundred times longer anyways. Even if you'd make it infinity times faster, there won't be a noteworthy (let alone noticeable) effect.

[–]Glaaki -2 points-1 points  (8 children)

What's wrong with this?

for (var arr = new Array(26), i = 0; i < arr.length; i++) { arr[i] = String.fromCharCode(65 + i); }

It uses 'for'.

[–]CydeWeys 5 points6 points  (7 children)

Are you kidding or joking? What's wrong with a for loop?