dom

JavaScript performance comparison

Test case created by eric

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
source code
Array.prototype.swap = function (i, j) {
    var k = this[i]; this[i] = this[j]; this[j] = k;
}

function bubbleSort(list) {
    var items = list.slice(0), swapped = false, p, q;
    for (p = 1; p < items.length; ++p) {
        for (q = 0; q < items.length - p; ++q) {
            if (items[q + 1] < items[q]) {
                items.swap(q, q + 1);
                swapped = true;
            }
        }
        if (document.documentElement.toString() != "") {
            document.documentElement.ownerDocument.createElement("BUTTON");
        }            
        if (!swapped)
            break;
    }
    return items;
}

var d = document.documentElement.ownerDocument;
d.getElementById("");

var N = 250, data = [];
while (N > 0) {
    data.push(N--);
    document.getElementById("");
    d.getElementById("");  
    var b = document.createElement("BUTTON");
    var t = document.createTextNode("CLICK ME");
    b.appendChild(t);
    b.removeChild(t);
}
bubbleSort(data);
 
pending…
source code transformé
// --------------------------------------------
// Dom Api Records Array  and functions  
// --------------------------------------------
var g_aDomApiRecords = new Array();

var g_mapDomApiRecords = new Object();

function mapHasKey(key) {
    if ( g_mapDomApiRecords[key] == null )
        return false;
    else
        return true;
}

function clearDomApiRecordsArray()
{
    g_aDomApiRecords = null;
    g_aDomApiRecords = new Array();

    g_mapDomApiRecords = null;
    g_mapDomApiRecords = new Object();
};

function updateDomApiRecordsMap(sApiName, iEachTime)
{
    if (mapHasKey(sApiName)) {
        g_mapDomApiRecords[sApiName].iCallNB += 1;
        g_mapDomApiRecords[sApiName].iTotalTime += g_mapDomApiRecords[sApiName].iEachTime;
        //g_mapDomApiRecords[sApiName].iTotalTime += iEachTime;
        //g_mapDomApiRecords[sApiName].iTotalTime = g_mapDomApiRecords[sApiName]. * ;
    }
    else {
        var o = new Object();
        o.sApiName = sApiName;
        o.iEachTime = iEachTime;
        o.iCallNB = 1;
        o.iTotalTime = iEachTime;
        g_mapDomApiRecords[sApiName] = o;
    }
};

function updateDomApiRecordsArray(sApiName, iEachTime)
{
    var bApiExist = false;
    var bAverageEachTime = 0.0;
    for (var i = 0; i < g_aDomApiRecords.length; i++) {
        if( g_aDomApiRecords[i].sApiName == sApiName ) {
            bApiExist = true;
            g_aDomApiRecords[i].iCallNB += 1;
            g_aDomApiRecords[i].iTotalTime += iEachTime;
            bAverageEachTime = g_aDomApiRecords[i].iTotalTime / g_aDomApiRecords[i].iCallNB;
            g_aDomApiRecords[i].iEachTime = bAverageEachTime;
//            if (iEachTime > g_aDomApiRecords[i].iEachTime)
//                g_aDomApiRecords[i].iEachTime = iEachTime;
            break;    
        }
    }

    if( !bApiExist ){
        var o = new Object();
        o.sApiName = sApiName;
        o.iEachTime = iEachTime;
        o.iCallNB = 1;
        o.iTotalTime = iEachTime;
        g_aDomApiRecords.push(o);
    }
};

function updatePercentInDomApiRecordsMap(iTotalExecuteTime) {
    var fPercent = 0.0;
    for (key in g_mapDomApiRecords) {
        //g_mapDomApiRecords[key].iTotalTime = g_mapDomApiRecords[key].iEachTime * g_mapDomApiRecords[key].iCallNB;
        fPercent = g_mapDomApiRecords[key].iTotalTime * 100 / iTotalExecuteTime;
        g_mapDomApiRecords[key].fPercent = fPercent;
    }  
};


function updatePercentInDomApiRecordsArray(iTotalExecuteTime)
{
    var fPercent = 0.0;
    for ( var i = 0; i < g_aDomApiRecords.length; i++){
       fPercent = g_aDomApiRecords[i].iTotalTime * 100/ iTotalExecuteTime;
       g_aDomApiRecords[i].fPercent = fPercent;
    }
};

// --------------------------------------------
// Benchmark Records Array  and functions  
// --------------------------------------------
var g_aBenchmarkRecords = new Array();

function clearBenchmarkRecordsArray() {
    g_aBenchmarkRecords = null;
    g_aBenchmarkRecords = new Array();
};

function updateBenchmarkRecordsArray(sBenchMarkName, bCreateObject, bModifyObject) {
    var bBenchMarkNameExist = false;
    for( var i = 0; i < g_aBenchmarkRecords.length; i++)
    {
        if( g_aBenchmarkRecords[i].sBenchMarkName == sBenchMarkName )
        {
            bBenchMarkNameExist = true;
            if( bCreateObject )
                g_aBenchmarkRecords[i].iNbCreatedObject += 1;
            if( bModifyObject )
                g_aBenchmarkRecords[i].iNbModifiedObject += 1;  
            break;          
        }
    }

    if( !bBenchMarkNameExist ) {
        var o = new Object();
        o.sBenchMarkName = sBenchMarkName;
        o.iNbCreatedObject = 0;
        o.iNbModifiedObject = 0;

        if( bCreateObject )
            o.iNbCreatedObject += 1;
        if( bModifyObject )
            o.iNbModifiedObject += 1;            

        g_aBenchmarkRecords.push(o);        
    }
};
updateBenchmarkRecordsArray("benchMark1", false, false);

function isDOMObject(o) {
    var sConstructorName = o.constructor.toString();
    if ( sConstructorName.indexOf("[object HTML") == 0 ||
         sConstructorName.indexOf("[object CanvasRenderingContext") == 0 )
        return true;
    return false;
};

function isCreateNodeDomApi(sApiName)
{
    if( sApiName.indexOf("create") == 0 )
        return true;
    return false;      
};

function isModifyNodeDomApi(sApiName)
{
    if ( sApiName.indexOf("remove") == 0 || sApiName.indexOf("set") == 0 ||
         sApiName.indexOf("append") == 0 || sApiName.indexOf("insert") == 0 ||
         sApiName.indexOf("reverse") == 0 )
        return true;
    return false;          
};

function recordCall(obj, funcName)
{
    var callstr;
    var returnValue;
    var st;
    var st2;
    var bIsDom;
    var strIdentifyDomApiCall;
    var strDomApiDefinition;
    var bIsDomApi = true;
    var bDomApiIsEstimated = false; ;

    if (obj == null)
        callstr = funcName + '(';
    else
        callstr = "obj" + "." + funcName + "(";

    // Identify DOM Object
    bIsDom = isDOMObject(obj);

    // Identify Dom Api, must run in Mozilla
    if ( navigator.appName.indexOf("Microsoft") == -1 ) {
        // In firefox
        if (bIsDom) {
//            strIdentifyDomApiCall = "obj" + "." + funcName + ".toString();";
//            strDomApiDefinition = eval(strIdentifyDomApiCall);
            strDomApiDefinition = obj[funcName].toString();

            //alert(strDomApiDefinition);
            if (strDomApiDefinition.indexOf("[native code]") != -1) {
                bIsDomApi = true;
                //alert("true");
            }
            else {
                bIsDomApi = false;
                //alert("false");
            }
        }
    }

    for (var i = 2; i < arguments.length; ++i) {
        callstr += (typeof (arguments[i]) == 'string') ? "'" + arguments[i] + "'" : 'arguments[' + i + ']';
        if (typeof (arguments[i + 1]) != 'undefined') callstr += ',';
    }
    callstr += ')';

    //bDomApiIsEstimated = mapHasKey(funcName);
    bDomApiIsEstimated = false;

    // Get begin time.
    if ( bIsDom && bIsDomApi && !bDomApiIsEstimated ) {
        if (navigator.appName.indexOf("Microsoft") == -1) {
            st = java.lang.System.nanoTime();
        } else {
            st = new Date().getTime();
        }
    }

    // Call original function.
    returnValue = eval(callstr);

    // Get end Time and get the costed time.
    if (bIsDom && bIsDomApi && !bDomApiIsEstimated) {
        //st2 = new Date().getTime() - st;
        if ( navigator.appName.indexOf("Microsoft") == -1 ) {
            st2 = (java.lang.System.nanoTime() - st) / 1000000;
        } else {
            st2 = new Date().getTime() - st;
            if (st2 == 0)
                st2 = 0.5;
        }
    }

    if ( bIsDom && bIsDomApi ) {
        //updateDomApiRecordsArray(funcName, st2);
        updateDomApiRecordsMap(funcName, st2);

        if (isCreateNodeDomApi(funcName)) {
           updateBenchmarkRecordsArray("benchMark1", true, false)
        }

        if (isModifyNodeDomApi(funcName)) {
            updateBenchmarkRecordsArray("benchMark1", false, true)
        }
    }

    return returnValue;
};

Array.prototype.swap = function (i, j) {
    var k = this[i];
    this[i] = this[j];
    this[j] = k;
};
function bubbleSort(list) {
    var items = recordCall(list, 'slice', 0), swapped = false, p, q;
    for (p = 1; p < items.length; ++p) {
        for (q = 0; q < items.length - p; ++q) {
            if (items[q + 1] < items[q]) {
                recordCall(items, 'swap', q, q + 1);
                swapped = true;
            }
        }
        if (recordCall(document.documentElement, 'toString') != '') {
            recordCall(document.documentElement.ownerDocument, 'createElement', 'BUTTON');
        }
        if (!swapped)
            break;
    }
    return items;
}
var d = document.documentElement.ownerDocument;
recordCall(d, 'getElementById', '');
var N = 250, data = [];
while (N > 0) {
    recordCall(data, 'push', N--);
    recordCall(document, 'getElementById', '');
    recordCall(d, 'getElementById', '');
    var b = recordCall(document, 'createElement', 'BUTTON');
    var t = recordCall(document, 'createTextNode', 'CLICK ME');
    recordCall(b, 'appendChild', t);
    recordCall(b, 'removeChild', t);
}
bubbleSort(data);
pending…

You can edit these tests or add even more tests to this page by appending /edit to the URL.

Compare results of other browsers

0 comments

Add a comment