TreeWalker vs Custom Treewalker (v6)

Revision 6 of this benchmark created by sandeep on


Preparation HTML

<script type="text/javascript">
var g_iCount=0;
var g_elmContainer;
var g_oNormalWalker;
var g_oFragWalker;
var g_elmFrag;
var g_oWalker2;
var g_elmWalker2;

var g_fragTreeWalker ;
var g_elemTreeWalker ;
var g_fragCusWalker ;
var g_elemCusWalker ;
var g_fragOptiWalker ;
var g_elemOptiWalker ;




function acceptNode(oElm)
{
    if(oElm)
    {
        var oAttrVal = oElm.getAttribute("test");
        var iVal = (oAttrVal != null)? parseInt(oAttrVal, 10) : 0;
        oElm.setAttribute("test",iVal);
    }
    g_iCount++;
    return NodeFilter.FILTER_ACCEPT;
}

var TreeWalker = function (elmRoot, lNodeFilterShowType, fnAcceptCheck, bEntityReferenceExpansion) {
   
 this._elmRoot = elmRoot;
    this._fnAcceptCheckCallback = fnAcceptCheck;
    this._elmCurrent = this._elmRoot;
    this._bShowElement = ((lNodeFilterShowType & 1) === 1);
    this._bShowText = ((lNodeFilterShowType & 4) === 4);
}
TreeWalker.prototype = {
    _elmRoot: null,
    _elmCurrent: null,
    _elmToNotProcessChildren: null,
    _fnAcceptCheckCallback: null,
    _bShowElement: false,
    _bShowText: false,
    
    walkThrough: function TreeWalker$walkThrough() {
        if (this._elmRoot == null || this._elmRoot == undefined) {
            return;
        }
        this._elmCurrent = this._elmRoot;
        if ((this._bShowElement && this._elmCurrent.nodeType === 1) || (this._bShowText && this._elmCurrent.nodeType === 3)) {
            if (this._fnAcceptCheckCallback(this._elmCurrent) === 2) {
                this._elmCurrent = null;
            }
        }
        while (this._elmCurrent != null) {
            if (this._elmCurrent !== this._elmToNotProcessChildren && this._elmCurrent.firstChild != null) {
                this._elmCurrent = this._elmCurrent.firstChild;
                if ((this._bShowElement && this._elmCurrent.nodeType === 1) || (this._bShowText && this._elmCurrent.nodeType === 3)) {
                    if (this._fnAcceptCheckCallback(this._elmCurrent) === 2) {
                        this._elmToNotProcessChildren = this._elmCurrent;
                    }
                }
            }
            else {
                while (this._elmCurrent !== this._elmRoot) {
                    if (this._elmCurrent.nextSibling != null) {
                        this._elmCurrent = this._elmCurrent.nextSibling;
                        if ((this._bShowElement && this._elmCurrent.nodeType === 1) || (this._bShowText && this._elmCurrent.nodeType === 3)) {
                            if (this._fnAcceptCheckCallback(this._elmCurrent) === 2) {
                                this._elmToNotProcessChildren = this._elmCurrent;
                            }
                        }
                        break;
                    }
                    else {
                        this._elmCurrent = this._elmCurrent.parentNode;
                    }
                }
                if (this._elmCurrent === this._elmRoot) {
                    this._elmCurrent = null;
                }
            }
        }
    }
}
function CreateWalker(root)
{
    return document.createTreeWalker(root,
                                     NodeFilter.SHOW_ELEMENT,
                                     acceptNode,
                                     true);
}


/// Optimized parser

TreeWalker2 = function (elmRoot, lNodeFilterShowType, fnAcceptCheck, bEntityReferenceExpansion) {

    this._elmRoot = elmRoot;
    this._fnAcceptCheckCallback = fnAcceptCheck;
    this._elmCurrent = this._elmRoot;
    this._bShowElement = ((lNodeFilterShowType & 1) === 1);
    this._bShowText = ((lNodeFilterShowType & 4) === 4);
}
TreeWalker2.prototype = {
    _elmRoot: null,
    _elmCurrent: null,
    _elmToNotProcessChildren: null,
    _fnAcceptCheckCallback: null,
    _bShowElement: false,
    _bShowText: false,
    
    walkThrough: function Kepler_Framework_Core_Browser_ProxyClasses_TreeWalker$walkThrough() {
        if (ss.isNullOrUndefined(this._elmRoot)) {
            return;
        }
        this._elmCurrent = this._elmRoot;
        if ((this._bShowElement && this._elmCurrent.nodeType === 1) || (this._bShowText && this._elmCurrent.nodeType === 3)) {
            if (this._fnAcceptCheckCallback(this._elmCurrent) === 2) {
                this._elmCurrent = null;
            }
        }
        while (this._elmCurrent != null) {
            var eleFirstChild = null;
            if (this._bShowText) {
                eleFirstChild = this._elmCurrent.firstChild;
            }
            else if (this._bShowElement) {
                eleFirstChild = this._elmCurrent.firstElementChild;
            }
            if (this._elmCurrent !== this._elmToNotProcessChildren && eleFirstChild != null) {
                this._elmCurrent = eleFirstChild;
                if (ss.isValue(this._elmCurrent)) {
                    if (this._fnAcceptCheckCallback(this._elmCurrent) === 2) {
                        this._elmToNotProcessChildren = this._elmCurrent;
                    }
                }
            }
            else {
                while (this._elmCurrent !== this._elmRoot) {
                    var eleNextSibling = null;
                    if (this._bShowText) {
                        eleNextSibling = this._elmCurrent.nextSibling;
                    }
                    else if (this._bShowElement) {
                        eleNextSibling = this._elmCurrent.nextElementSibling;
                    }
                    if (eleNextSibling != null) {
                        this._elmCurrent = eleNextSibling;
                        if (ss.isValue(this._elmCurrent)) {
                            if (this._fnAcceptCheckCallback(this._elmCurrent) === 2) {
                                this._elmToNotProcessChildren = this._elmCurrent;
                            }
                        }
                        break;
                    }
                    else {
                        this._elmCurrent = this._elmCurrent.parentNode;
                    }
                }
                if (this._elmCurrent === this._elmRoot) {
                    this._elmCurrent = null;
                }
            }
        }
    }
}





</script>
<div id="container">

<span id="document" name="document"><TABLE id="maintable" cellspacing="0" cellpadding="0" border="0" align="center" style="font-family:k_Calibri; font-size:16px;"  > <tr><td colspan="5" height="12px"></td></tr><tr><td bgcolor="#C6C6C6" colspan="5" height="1px"></td></tr><tr height="1056"><td nowrap width="816px" valign="top" style="background: no-repeat rgb(198,217,241);border-left:solid 1px #C6C6C6;"><div id="leftselection" posparentx="0" posparenty="12px" style="z-index:-1;position:absolute;left:0px;top:0px;width:95px;height:1056px"></div><span  style="width:816px"><div contenteditable="true"  name="editabletext" spellcheck="false" dir="ltr" style="z-index:2;position:relative;outline:none"><!--****************Section Start***************--><span id="section" sindex="1" enldtop = "1" enldbottom = "1" enldleft = "1" enldright = "1" enldgutter = "0" enldguttertype = "0" enlborientationportrait = "1" enlimultiplepages = "0" enliapplyto = "0" enlipapersize = "0" enldwidth = "8.5" enldheight = "11" enlifirstpage = "0" enliotherpage = "0" enliselectionstart = "2" enlbsuppressendnotes = "0" enlbdifferentoddeven = "0" enlbDifferentFirstPage = "0" enldheader = "0.5" enldfooter = "0.5" enliverticalalignment = "0" enlinoofcolumns = "1" enlipresets = "1" enldwid1 = "6.5" enldwid2 = "0" enldwid3 = "0" enldspa1 = "0" enldspa2 = "0" enlbequalcolumns = "1" enlblinebetween = "0"><!--******************** Page Start************************--><span id="page" name="page" pindex="1"><span id="para" name="para" propclass = "1" > <span id="row" name="row" rindex="1"><p class="p2"><font class="class1" viewfontsize="24">DOLPHINS</font></p>
</span></span><!--- Para End ---><span id="para" name="para" propclass = "2" > <span id="row" name="row" rindex="2"><p class="p3"><font class="class2" viewfontsize="11">Dolphins are marine mammals that are closely related to whales and porpoises. Dolphins are considered</font></p>
</span><span id="row" name="row" rindex="3"><p class="p4"><font class="class2" viewfontsize="11">to be amongst the most intelligent of animals and their often friendly appearance and seemingly playful</font></p>
</span><span id="row" name="row" rindex="4"><p class="p4"><font class="class2" viewfontsize="11">attitude have made them popular in human culture. </font></p>
</span></span><!--- Para End ---><span id="para" name="para" propclass = "2" > <span id="row" name="row" rindex="5"><p class="p31"><font class="class2" viewfontsize="11">Dolphins have a streamlined body adapted for fast swimming. The tail fin, called the </font><font class="class3" viewfontsize="11">fluke</font><font class="class2" viewfontsize="11">, is used for </font></p>
</span><span id="row" name="row" rindex="6"><p class="p4"><font class="class2" viewfontsize="11">propulsion, while the pectoral fins together with the entire tail section provide directional control. The </font></p>
</span><span id="row" name="row" rindex="7"><p class="p4"><font class="class2" viewfontsize="11"><span id="actselection_start"></span>dorsal fin<span id="actselection_end"></span> provides stability while swimming.</font></p>
</span></span><!--- Para End ---><span id="para" name="para" propclass = "2" > <span id="row" name="row" rindex="8"><p class="p31"><font class="class2" viewfontsize="11">Dolphins breathe through a blowhole located on the top of their head. The dolphin brain is large, highly</font></p>
</span><span id="row" name="row" rindex="9"><p class="p4"><font class="class2" viewfontsize="11">complex, and is different in structure from that of most land mammals.</font></p>
</span></span><!--- Para End ---><span id="para" name="para" propclass = "2" > <span id="row" name="row" rindex="10"><p class="p31"><font class="class2" viewfontsize="11">Most dolphins have acute eyesight, both in and out of the water. Their perception of sound is ten times</font></p>
</span><span id="row" name="row" rindex="11"><p class="p4"><font class="class2" viewfontsize="11">above the upper limit of adult human hearing.</font></p>
</span></span><!--- Para End ---><span id="para" name="para" propclass = "2" > <span id="row" name="row" rindex="1"><p class="p31"><font class="class2" viewfontsize="11">They communicate using a variety of clicks, whistles, and </font></p>
</span><span id="row" name="row" rindex="1"><p class="p4"><font class="class2" viewfontsize="11">other vocalizations. They also use ultrasonic sounds for </font></p>
</span><span id="row" name="row" rindex="1"><p class="p4"><font class="class2" viewfontsize="11">echolocation. Dolphin echolocation sounds are amongst </font></p>
</span><span id="row" name="row" rindex="1"><p class="p4"><font class="class2" viewfontsize="11">the loudest noises made by animals in the sea.</font></p>
</span></span><!--- Para End ---><span id="para" name="para" propclass = "2" > <span id="row" name="row" rindex="1"><p class="p31"><font class="class2" viewfontsize="11">Dolphins need to come up to the surface to breathe and </font></p>
</span><span id="row" name="row" rindex="1"><p class="p4"><font class="class2" viewfontsize="11">have to be alert for possible predators. They do not sleep </font></p>
</span><span id="row" name="row" rindex="1"><p class="p4"><font class="class2" viewfontsize="11">in the same way land mammals do. Generally, dolphins </font></p>
</span><span id="row" name="row" rindex="1"><p class="p4"><font class="class2" viewfontsize="11">sleep with only one hemisphere of the brain in slow-wave sleep at a time.</font></p>
</span></span><!--- Para End ---><span id="para" name="para" propclass = "2" > <span id="row" name="row" rindex="2"><p class="p31"><font class="class2" viewfontsize="11">Dolphins have long played a role in human culture. Dolphins are common in Greek mythology and there</font></p>
</span><span id="row" name="row" rindex="3"><p class="p4"><font class="class2" viewfontsize="11">are many coins which feature a man or boy riding on the back of a dolphin. The ancient Greeks treated</font></p>
</span><span id="row" name="row" rindex="4"><p class="p4"><font class="class2" viewfontsize="11">them with welcome; a ship spotting dolphins riding in their wake was considered a good omen for a</font></p>
</span><span id="row" name="row" rindex="5"><p class="p4"><font class="class2" viewfontsize="11">smooth voyage. In Hindu mythology, the Ganges River Dolphin is associated with Ganga, the deity of the</font></p>
</span><span id="row" name="row" rindex="6"><p class="p4"><font class="class2" viewfontsize="11">Ganges River.</font></p>
</span></span><!--Para End--></span><!--****************Page End***************--></span></div></span></td></tr><tr><td bgcolor="#C6C6C6" colspan="5" height="1px"></td></tr><tr><td colspan="5" height="20px"></td></tr></table><!-- Page 1 --><div id="floatingheader" name="floatingheader" posparentx="1px" posparenty="10px" style="position:absolute;top:0px;z-index:1;border:solid 0 red;"><table width="815px" cellspacing="0" cellpadding="0" align="center" border="0" style="FONT-SIZE:16px; font-family:Times New Roman;border-bottom:dashed 0 RGB(112,149,196)"><tbody><tr><td width="815px" height="95px"><div style="position:relative;z-index=-1"><br></div></td></tr></tbody></table></div><div id="floatingfooter" name="floatingfooter" posparentx="1px" posparenty="976px" style="position:absolute;margin-top:0px;z-index:1;border:solid 0 red;"><table width="815px" cellspacing="0" cellpadding="0" align="center" border="0" style="FONT-SIZE:16px; font-family:Times New Roman;border-top:dashed 0 RGB(112,149,196)"><tbody><tr><td width="815px" height="90px" align="right"><div style="position:relative;z-index:-1;padding-right:0px;font-style:italic;color:rgb(128,128,128);text-align:center">Ocean World</div></td></tr></tbody></table></div><div id="floatingseparator" name="floatingseparator" posparentx="468" posparenty="507px" style="position:absolute;top:-1000px;z-index:1px;"><img src="" /></div></span></div>

Setup

// Normal Tree Walker.
    g_elmContainer = document.getElementById("container");
    g_oNormalWalker = CreateWalker(g_elmContainer);
    
    // Custome Tree Walker.
    g_elmFrag = document.createDocumentFragment();
    var elmFragCntnr = g_elmContainer.cloneNode();
    //g_elmFrag.appendChild(elmFragCntnr);
    g_oFragWalker = new TreeWalker(elmFragCntnr, NodeFilter.SHOW_ELEMENT, acceptNode, true);
    
    // Custom Optimized Tree Walker
    var elmFragCntnr2 = g_elmContainer.cloneNode();
    g_elmWalker2 = new TreeWalker2(elmFragCntnr2, NodeFilter.SHOW_ELEMENT, acceptNode, true);
    
    // Normal Tree walker DF
    g_elemTreeWalker = document.createDocumentFragment();
    var elmFragCntnrNormal = g_elmContainer.cloneNode();
    g_elemTreeWalker.appendChild(elmFragCntnrNormal);
    g_fragTreeWalker = CreateWalker(elmFragCntnrNormal);
    
    // Custom Tree walker DF
    g_elemCusWalker = document.createDocumentFragment();
    var elmFragCustomContainerRoot = g_elmContainer.cloneNode();
    g_elemCusWalker.appendChild(elmFragCustomContainerRoot);
    g_fragCusWalker = new TreeWalker(elmFragCustomContainerRoot, NodeFilter.SHOW_ELEMENT, acceptNode, true);
    
    
    // Optimized Tree walker DF
    g_elemOptiWalker = document.createDocumentFragment();
    var eleroot = g_elmContainer.cloneNode();
    g_elemOptiWalker.appendChild(eleroot);
    g_fragOptiWalker = new TreeWalker2(eleroot, NodeFilter.SHOW_ELEMENT, acceptNode, true);

Teardown


    //TreeWalker
    g_elmContainer = null;
    g_oNormalWalker = null;
    g_elmFrag = null;
    
    // Custome Tree Walker
    g_oFragWalker = null;
    
    // Custom Optimized tree walker
    g_elmWalker2 = null;
    
    
    g_fragTreeWalker = null;
    g_elemTreeWalker = null;
    g_fragCusWalker = null;
    g_elemCusWalker = null;
    g_fragOptiWalker = null;
    g_elemOptiWalker = null;
  

Test runner

Ready to run.

Testing in
TestOps/sec
Normal Walker on normal Doc
g_oNormalWalker = CreateWalker(g_elmContainer);
g_iCount = 0;
while (g_oNormalWalker.nextNode() != null);
console.log("Tree Walker :" + g_iCount);
ready
custom tree walker
g_oFragWalker = new TreeWalker(elmFragCntnr, NodeFilter.SHOW_ELEMENT, acceptNode, true);
g_iCount = 0;
g_oFragWalker.walkThrough();
console.log("Custome Tree Walker :" + g_iCount);
ready
optimized walker
g_elmWalker2 = new TreeWalker(elmFragCntnr2, NodeFilter.SHOW_ELEMENT, acceptNode, true);
g_iCount = 0;
g_elmWalker2.walkThrough();
console.log("Custome Tree Walker Optimized :" + g_iCount);
ready
normal walker , DF
g_fragTreeWalker = CreateWalker(elmFragCntnrNormal);
g_iCount = 0;
while (g_fragTreeWalker.nextNode() != null);
console.log("Tree Walker , DF :" + g_iCount);
ready
Custom Walker DF
g_fragCusWalker = new TreeWalker(elmFragCustomContainerRoot, NodeFilter.SHOW_ELEMENT, acceptNode, true);
g_iCount = 0;
g_fragCusWalker.walkThrough();
console.log("Custome Tree Walker DF :" + g_iCount);
ready
optimized walker DF
g_fragOptiWalker = new TreeWalker(eleroot, NodeFilter.SHOW_ELEMENT, acceptNode, true);
g_iCount = 0;
g_fragOptiWalker.walkThrough();
console.log("Custome Tree Walker Optimized DF:" + g_iCount);
ready

Revisions

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