Javascript looping through large dictionary yields unresponsive script - javascript

I'm making a firefox addon that appends words with other words in html text. This code works, but when iterating through an enormous dictionary, I get an unresponsive script error.
What is the best way to improve the speed of this loop?
Splitting up the dictionary into smaller objects? Or setting a timeout function?
var brands = {"manykeys" : "manyvalues"};
function replaceWord(){
for (var key in brands){
htmlreplace(key, key + " (" + brands[key] + ")");
}
}
function htmlreplace(a, b, element) {
if (!element) element = document.body;
var nodes = element.childNodes;
for (var n=0; n<nodes.length; n++) {
if (nodes[n].nodeType == Node.TEXT_NODE) {
var r = new RegExp(a, 'g');
nodes[n].textContent = nodes[n].textContent.replace(r, b);
} else {
htmlreplace(a, b, nodes[n]);
}
}
}
replaceWord();

There are some considerations to take. It depends a lot on what you can change or not. One of the bigger improvements you can do is using array instead of key/value object.
var brands = [
['manykeys0000','manyvalues0000'],
['manykeys0001','manyvalues0001'],
['manykeys0002','manyvalues0002'],
['manykeys0003','manyvalues0003'],
['manykeys0004', ...
];
function replaceWord(){
var i, n = brands.length;
for (i = 0; i < n; ++i) {
htmlreplace(brands[i][0], brands[i][0] + " (" + brands[i][1] + ")");
}
}
A couple of other changes should also give a tiny improvement:
1.) Move nodes.length outside the loop.
2.) If suitable pass document.body from replaceWord()
var body = document.body;
...
htmlreplace(brands[i][0], brands[i][0] + " (" + brands[i][2] + ")", body);
function htmlreplace(a, b, element) {
var nodes = element.childNodes, len = nodes.length;
for (var n=0; n < len; ++n) {
Combined quick benchmark on Chrome and Firefox gave a 30-40% increase in speed.
Other edits to test out:
Move var r = new RegExp(a, 'g'); to replaceWord(), and pass it as first argument to htmlreplace() instead of a.
function replaceWord(){
var i, n = brands.length;
for (i = 0; i < n; ++i) {
var r = new RegExp(brands[i][0], 'g');
htmlreplace(r, brands[i].join(' (') + ')', elem);
}
}
If you play with timeout this article might be of interest. It uses
window.postMessage();
to implement a custom setZeroTimeout() but not sure how it will impact your case.
Beside JSPerf etc. use profiling tools in browser, for example in Chrome, which might be better suited for what you do in your code.

I haven't tried, but doing this might work:
function replaceWord(){
for (var key in brands){
(function(key) {
setTimeout(function() {
htmlreplace(key, key + " (" + brands[key] + ")");
}, 0);
})(key);
}
}
The idea is that you postpone the replacing for when the browser has time for it, instead of doing it monolithically and making the browser freeze while it's thinking.

The bottleneck in your code is not the dictionary size, unless it is really big, but the DOM traversal.
Get the text nodes once and then work with them.
var textnodes = $x("//text()", document.body)
function $x(p, context) {
if (!context) context = document;
var i, arr = [], xpr = document.evaluate(p, context, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
for (i = 0; item = xpr.snapshotItem(i); i++) arr.push(item);
return arr;
}
You should see a considerable speed improvement.

Related

Quickly and efficiently switch array elements

I am trying to swap the data within these arrays.
My data will look something like this. In production this array can and will be several times bigger.
var data = [
[13.418946862220764, 52.50055852688439],
[13.419011235237122, 52.50113000479732],
[13.419756889343262, 52.50171780290061],
[13.419885635375975, 52.50237416816131],
[13.420631289482117, 52.50294888790448]
]
Currently my switching code looks like the below.
var temp;
for(var i = 0;i < data.length;i++) {
temp = array[i][0];
array[i][0] = array[i][1];
array[i][1] = temp;
}
What I am trying to figure out is if this the most efficient way to do this and/or if any improvements are possible.
Please understand that even the slightest improvement will matter.
I would use a more functional approach:
var switched = data.map(function (arr) {
return [arr[1], arr[0]];
});
If you use ES2015, you can even do that in one line:
const switched = data.map((arr) => [arr[1], arr[0]]);
If you want to stick with a loop:
for(var i = 0; i < data.length; i++) {
data[i] = [data[i][1], data[i][0]];
}
You code looks perfectly fine, and you don't need any further "optimization".
As always, a benchmark is always the good way to find out who is faster:
var arr = (function() {
var res = [];
for(var i = 0; i < 100000; ++i) {
res[i] = [Math.random(), Math.random()];
}
return res;
}());
var swap_in_place = function() {
for(var i = 0; i < arr.length; ++i) {
var tmp = arr[i][0];
arr[i][0] = arr[i][1];
arr[i][1] = tmp;
}
};
var swap_map = function() {
arr = arr.map(function(elem) {return [elem[1], elem[0]]; });
};
var runBench = function(name, f) {
var start = new Date().getTime();
for(var i = 0; i < 50; ++i) {
f();
}
var stop = new Date().getTime();
console.log(name + " took: " + (stop - start));
};
runBench("in_place", swap_in_place);
runBench("map", swap_map);
in my firefox latest (windows 10 x64), I get (quite consistently) 16 for in place, vs 350 for map version, meaning you get a 20x speed down by using map instead of your own version.
You might think this is due to the fact that this snippet is embedded in a iframe and so on, so I ran it in node (4.5.0), which is built on top of V8, and I get the same results:
I think that the Jitter can't be smart enough to properly inline the function in the map version, or deduce it operates on the same memory without side effect. Thefore, the Jitter has to allocate a full new array to store the intermediate results, then loop over it with a function call (meaning register save/restore stall at each iteration), and then either:
copy back the entire data to arr
move the reference (probably what happens), but the garbage collector has to collect the entire temporary array.
The map function might also trigger reallocation of the temporary, which is extremely expensive.

How do I add specific requirements to this recursive hashtag generator?

I'm trying to build a hashtag generator with one specific requirement. The function below works well but I want to exclude all hashtags that are comprised of just one word. This is a brain teaser I just can't wrap my mind around.
function hashtag(string) {
var words = string.split(" ");
var result = [];
var f = function(prefix, words) {
for (var i = 0; i < words.length; i++) {
result.push(prefix + words[i]);
f(prefix + words[i], words.slice(i + 1));
}
};
f('#', words);
return result;
}
Running hashtag("Golden Gate Bridge"); will produce...
[ '#Golden', '#GoldenGate', '#GoldenGateBridge', '#GoldenBridge', '#Gate', '#GateBridge', '#Bridge' ]
I would like it to produce...
['#GoldenGate', '#GoldenGateBridge', '#GoldenBridge', '#GateBridge']
Note that all the single word origin hashtags are gone.
I tried adding in a "depth" variable that incremented with each additional level of recursion and tried some "if" statements but couldn't find the right combination.
Thanks for your help! I really appreciate it.
You were on the right path adding a depth counter.
function hashtag(string) {
var words = string.split(" ");
var result = [];
var f = function(prefix, words, depth) {
for (var i = 0; i < words.length; i++) {
// Only add this hashtag if our prefix depth is > 1
if (depth > 1) {
result.push(prefix + words[i]);
}
// Increase the prefix depth with each iteration.
f(prefix + words[i], words.slice(i + 1), depth + 1);
}
};
// Pass the default depth
f('#', words, 1);
return result;
}
You can see this working here: http://jsfiddle.net/3Kgzf/

.append VS .html VS .innerHTML performance

This site's run a test between the 3 different methods and it seems .html is the fastest, followed by .append. followed by .innerHTML. Can someone explain to me the reasons why?
Here's the site which does the comparison among the three methods.
I have read this this SO question which is related but I don't really understand the given answer, and the question didn't really elaborate much regarding .innerHtml.
I don't understand the following part:
A temporary element is created, let's call it x. x's innerHTML is set to the string of HTML that you've passed. Then jQuery will transfer each of the produced nodes (that is, x's childNodes) over to a newly created document fragment, which it will then cache for next time. It will then return the fragment's childNodes as a fresh DOM collection.
Note that it's actually a lot more complicated than that, as jQuery does a bunch of cross-browser checks and various other optimisations. E.g. if you pass just <div></div> to jQuery(), jQuery will take a shortcut and simply do document.createElement('div').
Can someone simplify this?
All three are slow to me. Modifying the dom on each iteration is slow.
http://jsperf.com/jquery-append-vs-html-list-performance/24
I just added a new test in there:
var html = [];
for (var i = 0; i < len; i++) {
html.push('<div>Test ' + i + '</div>');
}
document.getElementById('list').innerHTML = html.join('');
This is much faster again. :)
My method in Firefox does 26k Ops/sec vs 1,000, 10,000, and 13
That benchmark is worthless. innerHTML is always faster than DOM manipulation.
jQuery seems faster because it prepares a string with all the HTML first while the others do one operation each iteration. Also note that jQuery.html() uses innerHTML whenever it can.
jQuery from benchmark
var html = '';
for (var i = 0; i < len; i++) {
html += '<div>Test ' + i + '</div>';
}
$('#list').html(html);
innerHTML from benchmark
var list = document.getElementById('list');
for (var i = 0; i < len; i++) {
list.innerHTML = list.innerHTML + '<div>Test ' + i + '</div>';
}
The test for innerHTML would be a lot faster if it was written like:
var list = document.getElementById('list');
var html = '';
for (var i = 0; i < len; i++) {
html += '<div>Test ' + i + '</div>';
}
list.innerHTML = html;
http://jsben.ch/#/yDvKH
How can .html be faster than .innerHTML when the .html is using .innerHTML with a lot of extra code? Here .html implementation in jQuery (taken directly from jQuery file).
html: function( value ) {
return jQuery.access( this, function( value ) {
var elem = this[0] || {},
i = 0,
l = this.length;
if ( value === undefined ) {
return elem.nodeType === 1 ?
elem.innerHTML.replace( rinlinejQuery, "" ) :
undefined;
}
// See if we can take a shortcut and just use innerHTML
if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) &&
( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
!wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
value = value.replace( rxhtmlTag, "<$1></$2>" );
try {
for (; i < l; i++ ) {
// Remove element nodes and prevent memory leaks
elem = this[i] || {};
if ( elem.nodeType === 1 ) {
jQuery.cleanData( getAll( elem, false ) );
elem.innerHTML = value;
}
}
elem = 0;
// If using innerHTML throws an exception, use the fallback method
} catch(e) {}
}
if ( elem ) {
this.empty().append( value );
}
}, null, value, arguments.length );
}
As Bart said, innerHTML is always faster than DOM manipulation.
I was testing hyperHTML, so I thought I share my results. I didn't actually run my benchmarks in CodePen originally, and there is an interesting difference in that the jQuery times are much closer to innerHTML running in CodePen.
Chrome:
createFragment 312.80 ms
hyperHTML 253.10 ms
innerHTML 62.70 ms
$.append 183.40 ms
Chrome (extensions off):
createFragment 225.10 ms
hyperHTML 139.80 ms
innerHTML 47.80 ms
$.append 170.90 ms
Firefox:
createFragment 141 ms
hyperHTML 84 ms
innerHTML 25 ms
$.append 90 ms
Edge:
createFragment 422.50 ms
hyperHTML 184.60 ms
innerHTML 44.00 ms
$.append 1629.69 ms
IE11:
createFragment 1180.29 ms
hyperHTML 13315.59 ms //slow fallbacks, IE sucks
innerHTML 125.70 ms
$.append 2382.49 ms
I think it is all pretty simple. JavaScript is not as fast as the browser at parsing and creating elements, because the browser is machine specific compiled code. You can't do better than just handing over the HTML and letting the browser do the work without interruption.
It is possible that some of the performance differences are due to XSS checking, which would seem prudent.
function runbench(){
var data = [];
for (var i = 0; i < 10001; i++) {
data.push("<span>" + i + "</span>");
}
var perf=[];
var t0 = performance.now();
var c = document.createDocumentFragment();
for (var i = 0; i < 10001; i++) {
var e = document.createElement("span");
e.innerHTML = data[i];
c.appendChild(e);
}
document.querySelector('#createFragment').appendChild(c);
document.querySelector('#createFragment').classList='done';
var t1 = performance.now();
perf.push(t1-t0);
var t0 = performance.now();
document.querySelector('#innerHTML').innerHTML = data.join('');
document.querySelector('#innerHTML').classList='done';
var t1 = performance.now();
perf.push(t1-t0);
var t0 = performance.now();
$('#jqhtml').html(data.join(''));
document.querySelector('#jqhtml').classList='done';
var t1 = performance.now();
perf.push(t1-t0);
var t0 = performance.now();
$('#jqappend').append(data.join(''));
document.querySelector('#jqappend').classList='done';
var t1 = performance.now();
perf.push(t1-t0);
var t0 = performance.now();
hyperHTML.bind(document.querySelector('#hyperHTML'))
`${data.map(function (item) {
return "<span>" + item + "</span>";
})}`;
document.querySelector('#hyperHTML').classList='done';
var t1 = performance.now();
perf.push(t1-t0);
var stats = [];
stats.push("<table>")
stats.push("<tr><td>createFrag: </td><td>" + perf[0].toFixed(2) + "</td></tr>");
stats.push("<tr><td>innerHTML: </td><td>" + perf[1].toFixed(2) + "</td></tr>");
stats.push("<tr><td>$.html: </td><td>" + perf[2] .toFixed(2) + "</td></tr>");
stats.push("<tr><td>$.append: </td><td>" + perf[3] .toFixed(2) + "</td></tr>");
stats.push("<tr><td>hyperHTML: </td><td>" + perf[4].toFixed(2) + "</td></tr>");
stats.push("</table>");
$('#performance').html(stats.join(''));
document.querySelector('#performance').classList='done';
}
https://codepen.io/jwhooper/pen/GzKwMV
I think the innerHTML is faster with suggesstion #Brat.
And on creating loop and appending string should be good on using variable first.
It is make your performance more good.
good code:
var html = '';
for (var i = 0; i < len; i++) {
html += '<div>Test ' + i + '</div>';
};
$('#list').append(html);
not efficient code:
for (var i = 0; i < len; i++) {
var html = '<div>Test ' + i + '</div>';
$('#list').append(html);
}
for example: http://jsben.ch/#/yDvKH
I also had a problem with big table redraw (about 10x100 size). It takes about 300ms to redraw whole table.
The reason was not in the jQuery.append() and not in dom.innerHTML, but in appending each element each time.
The fastest way is to concatenate all elements html code and then append it to DOM.
Like this:
function redrawMyTable( myData )
{
var innerHTML = '';
for ( var i = 0; i < myData.length; i++ )
{
innerHTML += createRowFromData( myData[i] );
}
myTableTbody.innerHTML = innerHTML;
}
function createRowFromData( rowData )
{
var rowHTML = '';
for ( var i = 0; i < rowData.length; i++ )
{
rowHTML += createCellFromData( rowData[i] );
}
return rowHTML;
}
function createCellFromData( cellData )
{
//Do everything you need, and return HTMl code as a string
return cellHTML;
}
Now it takes only 20-30 ms (against 300ms :))
6 years later
Point is - don't manipulate the live DOM. Do it outside. Today, it doesn't matter where. You can use a HTML String, a DocumentFragment (which excludes Internet Explorer) or create a new Element but don't add it to the DOM, fill it as you need and THEN add it.
On Chrome and Firefox my observation is that it's all the same run time, give or take a few percent.
Building a long HTML String in chunks that are stored in an array and then join('')-ed is also not necessary any more. Years ago, I measured big time differences. Not today. Point one: there's no recognizable time difference (on Chrome and FF), and point two: the time isn't lost at this point, but in rendering.
my code innerHTML vs fragment
fragment use
running time : 1300~1500ms
innerHTML use
running time : 1800~2000ms
`
const data = [];
for(let i = 0; i < 1000001;i++){
data.push(i);
}
function useInnerHtml(result_wrap){
let text = ''
for(const item of data){
text += '<div>' + item + '</div>';
}
result_wrap.innerHTML = text;
}
function useFragment(result_wrap){
const fragment= new DocumentFragment(); // or document.createDocumentFragment();
for(const item of data){
const div = document.createElement('div');
div.textContent = item;
fragment.appendChild(div);
}
result_wrap.appendChild(fragment);
}
function createData(obj){
let startTime = new Date().getTime();
const targetParentNode = obj.parentNode;
const result_wrap = targetParentNode.querySelector('.result-wrap');
if(result_wrap.hasChildNodes() == false){
if(result_wrap.className.includes('inner-html')){
useInnerHtml(result_wrap);
}else if(result_wrap.className.includes('fragment')){
useFragment(result_wrap, targetParentNode);
}else{
alert('');
}
}else{
alert('click remove button');
}
let endTime = new Date().getTime();
let time = (endTime - startTime);
targetParentNode.querySelector('.running-time').textContent = 'running time : ' + time + 'ms'
}
function removeContent(){
[...document.querySelectorAll('.result-wrap')].map(e=>e.replaceChildren());
}
`
https://codepen.io/joohyoungkim19940805/pen/BaJQeGW

Multiple specials characters replacement optimization

I need to replace all the specials characters in a string with javascript or jQuery.
I am sure there is a better way to do this.
But I currently have no clue.
Anyone got an idea?
function Unaccent(str) {
var norm = new Array('À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï', 'Ð','Ñ','Ò','Ó','Ô','Õ','Ö','Ø','Ù','Ú','Û','Ü','Ý','Þ','ß', 'à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð','ñ', 'ò','ó','ô','õ','ö','ø','ù','ú','û','ü','ý','ý','þ','ÿ');
var spec = new Array('A','A','A','A','A','A','A','C','E','E','E','E','I','I','I','I', 'D','N','O','O','O','0','O','O','U','U','U','U','Y','b','s', 'a','a','a','a','a','a','a','c','e','e','e','e','i','i','i','i','d','n', 'o','o','o','o','o','o','u','u','u','u','y','y','b','y');
for (var i = 0; i < spec.length; i++) {
str = replaceAll(str, norm[i], spec[i]);
}
return str;
}
function replaceAll(str, search, repl) {
while (str.indexOf(search) != -1) {
str = str.replace(search, repl);
}
return str;
}
Here's a version using a lookup map that works a little more efficiently than nested loops:
function Unaccent(str) {
var map = Unaccent.map; // shortcut
var result = "", srcChar, replaceChar;
for (var i = 0, len = str.length; i < len; i++) {
srcChar = str.charAt(i);
// use hasOwnProperty so we never conflict with any
// methods/properties added to the Object prototype
if (map.hasOwnProperty(srcChar)) {
replaceChar = map[srcChar]
} else {
replaceChar = srcChar;
}
result += replaceChar;
}
return(result);
}
// assign this here so it is only created once
Unaccent.map = {'À':'A','Á':'A','Â':'A'}; // you fill in the rest of the map
Working demo: http://jsfiddle.net/jfriend00/rRpcy/
FYI, a Google search for "accent folding" returns many other implementations (many similar, but also some using regex).
Here's a bit higher performance version (2.5x faster) that can do a direct indexed lookup of the accented characters rather than having to do an object lookup:
function Unaccent(str) {
var result = "", code, lookup, replaceChar;
for (var i = 0, len = str.length; i < len; i++) {
replaceChar = str.charAt(i);
code = str.charCodeAt(i);
// see if code is in our map
if (code >= 192 && code <= 255) {
lookup = Unaccent.map.charAt(code - 192);
if (lookup !== ' ') {
replaceChar = lookup;
}
}
result += replaceChar;
}
return(result);
}
// covers chars from 192-255
// blank means no mapping for that char
Unaccent.map = "AAAAAAACEEEEIIIIDNOOOOO OUUUUY aaaaaaaceeeeiiiionooooo uuuuy y";
Working demo: http://jsfiddle.net/jfriend00/Jxr9u/
In this jsperf, the string lookup version (the 2nd example) is about 2.5x faster.
Using an object as a map is a good idea, but given the number of characters you're replacing, it's probably a good idea to pre-initialize the object so that it doesn't have to be re-initialized each time the function gets run (assuming you're running the function more than once):
var Unaccent = (function () {
var charMap = {'À':'A','Á':'A','Â':'A','Ã':'A','Ä':'A' /** etc. **/};
return function (str) {
var i, modified = "", cur;
for(i = 0; i < str.length; i++) {
cur = str.charAt(i);
modified += (charMap[cur] || cur);
}
return modified;
};
}());
This will front-load the heavy lifting of the function to page load time (you can do some modifications to delay it until the first call to the function if you like). But it will take some of the processing time out of the actual function call.
It's possible some browsers will actually optimize this part anyway, so you might not see a benefit. But on older browsers (where performance is of greater concern), you'll probably see some benefit to pre-processing your character map.
You can prepare key value pair type of array and via jquery each traverse that array.
Example :
function Unaccent(str) {
var replaceString = {'À':'A','Á':'A','Â':'A'}; // add more
$.each(replaceString, function(k, v) {
var regX = new RegExp(k, 'g');
str = str.replace(regX,v);
});
}
Working Demo
Good Luck !!

For loop speed performance in javascript

I went throught http://www.youtube.com/watch?v=mHtdZgou0qU speed up your javascript.
So i did this personal speed test:
var count = 50000000;
var testDummy;
// test 1
testDummy = 0;
var test1Start = new Date().getTime();
var i;
for (i=0;i<count;i++) {
testDummy++;
}
var test1End = new Date().getTime();
var test1Total = (test1End-test1Start);
// test 2
testDummy = 0;
var test2Start = new Date().getTime();
var i
for (i=count; i--;) {
testDummy++;
}
var test2End = new Date().getTime();
var test2Total = (test2End-test2Start);
debug(
"test1\n" +
"total: " + test1Total + "\n" +
"test2\n" +
"total: " + test2Total
);
I get not significant results, like sometimes they are even and sometimes not.
My question is, if i use for loop like this: "for(i=count;i--;)" is it really faster ?
Am i doing something wrong in my tests.
Thanks for your help!
(I'd write this as a comment, but it'd be too long.)
First: Worrying about the efficiency of a for loop is almost always a waste of (your own) time. What's inside of the loop usually has much more impact on performance than the details of how the loop is specified.
Second: What browser(s) did you test with? Different browsers will show different performance profiles; even different versions of the same browser will differ.
Third: It's not out of the question that the JavaScript engine optimized your loops out of the picture. A JavaScript compiler could simply look at the loop and decide to set testDummy to 50000000 and be done with it.
Fourth: If you really want to split hairs on performance, I'd try for(i=count; --i != 0;) as well as for(i=count;i--;). The former may save a machine instruction or two, because executing the subtraction (in the predecrement step) may automatically set a hardware flag indicating that the result was 0. That flag is potentially wasted when you're using the postdecrement operator, because it wouldn't be examined until the start of the next iteration. (The chances that you'd be able to notice the difference are slim to none.)
Well...
for( i=0 ; i < len ; i++ )
is practically the same as
for( i = len ; i-- ; )
Lets describe it:
case 1:
let i be 0
boolean expression
let i be i + 1
case 2:
let i be len
let i be i - 1
cast i to boolean (type coersion) and interpret it.
The difference should be minute and depends entirely on how efficient type coersion is compared to a normal boolean expression.
Incidentally, test this:]
var i = count;
while( i-- ) {}
There's nothing wrong with your tests.
The blocks that you are testing are very-near identical, meaning the difference in execution speeds are going to be trivial. In both examples, a variable (i) is set to a fixed value and looped until it reaches a fixed value (count). The only thing that differs is i++ and i--, which in terms of speed, I think are practically the same.
The thing you have to be careful of (not do) is calculate the "loop until" value inside the loop definition.
I have made some tests too, here are the results.
In many articles, books authors propose that "optimized" loops are faster.
It seems that modern browsers have some optimizations for "normal" loops.
Firefox 13.0.1
Normal Loop: 0.887
Opt1: 1.025
Opt2: 1.098
Opt3: 1.399
Chrome 19.0.1
Normal Loop: 3.349
Opt1: 3.12
Opt2: 3.109
Opt3: 3.095
IE8
Over 12sec...
Repeatedly crashed during tests.
<script type="text/javascript">
function p(p) { console.log(p); }
// function p(p) { document.write(p); }
var testFn = function(num, niz, fn) {
var start = new Date().getTime();
fn(num, niz);
var result = (new Date().getTime() - start) / 1000;
return result;
}
function normalLoop(num, niz) {
for (var i = 0; i < niz.length; i++) {
niz[i] = 'a' + i;
}
}
function opt1(num, niz) {
var len = niz.length;
for (var i = 0; i < len; i++) {
niz[i] = 'a' + i;
}
}
function opt2(num, niz) {
for (var i = niz.length; i--;) {
niz[i] = 'a' + i;
}
}
function opt3(num, niz) {
while(i--) {
niz[i] = 'a' + i;
}
}
var niz = [];
var num = 10000000;
for (var i = 0; i < num; i++) { niz.push(i); };
p('Normal Loop: ' + testFn(num, niz, normalLoop));
p('Opt1: ' + testFn(num, niz, opt1));
p('Opt2: ' + testFn(num, niz, opt2));
p('Opt3: ' + testFn(num, niz, opt3));
</script>

Categories

Resources