<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
    <title>JavaScript Rules - performance</title>
    <link href="http://javascriptrules.com/category/performance.xml" rel="self"/>
    <link href="http://javascriptrules.com"/>
    <updated>2012-03-08T18:28:28-08:00</updated>
    <id>http://javascriptrules.com/category/performance</id>
    <author>
        <name>Marcel Duran</name>
        <email>marcelduran@gmail.com</email>
    </author>
 
    
    
    
    
    
    
    
    
    
    
    <entry>
        <title>Web Metrics Framework</title>
        <link href="http://javascriptrules.com/2010/08/25/web-metrics-framework"/>
        <updated>2010-08-25T00:00:00-07:00</updated>
        <id>/2010/08/25/web-metrics-framework</id>
        <content type="html">&lt;p&gt;Recently &lt;a href='http://code.google.com/speed/articles/web-metrics.html'&gt;Google Web Metrics&lt;/a&gt; report came across and inspired by my co-worker Stoyan Stefanov&amp;#8217;s &lt;a href='http://www.phpied.com/wtf/'&gt;WTF - Web Testing Framework&lt;/a&gt; I decided to build my own ruleset for &lt;a href='http://developer.yahoo.com/yslow/'&gt;YSlow&lt;/a&gt; using these metrics to check how good or bad pages are compared to Top and All Sites averages.&lt;/p&gt;

&lt;p&gt;Last edition of &lt;a href='http://en.oreilly.com/velocity2010'&gt;O&amp;#8217;Reilly Velocity Conference&lt;/a&gt;, Stoyan demonstrated &lt;a href='http://en.oreilly.com/velocity2010/public/schedule/detail/15306'&gt;how easy is to build your own YSlow ruleset&lt;/a&gt; and following his &lt;a href='http://www.phpied.com/wtf/'&gt;post&lt;/a&gt; and &lt;a href='http://github.com/stoyan/Web-Testing-Framework/'&gt;source code&lt;/a&gt; I was able to make it. This first release of this &lt;a href='http://labs.javascriptrules.com/wmf/'&gt;extension&lt;/a&gt; of &lt;a href='http://developer.yahoo.com/yslow/'&gt;extension&lt;/a&gt; of &lt;a href='http://getfirebug.com/'&gt;extension&lt;/a&gt; features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Web Metrics from 2010-05-26&lt;/li&gt;

&lt;li&gt;Top and All Sites metrics rulesets&lt;/li&gt;

&lt;li&gt;Use percentile to score when available&lt;/li&gt;

&lt;li&gt;Use SSH metrics for HTTPS pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src='http://javascriptrules.com/images/wmf.png' alt='Screenshot: Web Metrics Framework for YSlow for Firebug for Firefox' /&gt;&lt;/p&gt;

&lt;h3 id='gimme'&gt;Gimme!&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The code is &lt;a href='http://github.com/marcelduran/Web-Metrics-Framework'&gt;in GitHub&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Install it from &lt;a href='https://addons.mozilla.org/en-US/firefox/addon/221495/'&gt;Mozilla Addon Page&lt;/a&gt; or &lt;a href='http://labs.javascriptrules.com/wmf/download/'&gt;Download Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='usage'&gt;Usage&lt;/h3&gt;

&lt;p&gt;After installing this extension you will see 2 new rulesets in the YSlow rulesets drop down list:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Web Metrics Framework - Top Sites&lt;/li&gt;

&lt;li&gt;Web Metrics Framework - All Sites&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Choose one of these rulesets and click &lt;strong&gt;Run Test&lt;/strong&gt; button. The current page will be evaluated using the Google web metrics data.&lt;/p&gt;

&lt;h3 id='metrics'&gt;Metrics&lt;/h3&gt;

&lt;p&gt;The metrics provided by Google on its article are mainly averages with some percentiles and SSL data. YSlow rules need a lint function that evaluates an input returning a score from 0 to 100 which is later used to give the F to A score system using weights.&lt;br /&gt;Since not all metrics have percentiles I had to compare the page metrics with the average multiplied by a magic number (4) to create a range from 0 to 4 * average (if any statistic savvy here has comments on it please help me out to find a better way to evaluate) which is good enough to have an outcome where being in the average deserves a C. Perhaps Google releases new reports in future updates with all metrics percentiles, this extension could benefit from those numbers and become more accurate.&lt;br /&gt;If the page being checked is secure (HTTPS), the SSL data available on the report is used instead. The weighting distribution was given by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Every metric starts with 1&lt;/li&gt;

&lt;li&gt;Metrics with percentile get 1 more&lt;/li&gt;

&lt;li&gt;Metrics directly related to wire traffic payload or number of requests also get 1 more&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Again: statistics savvy, help me improving this extension with your valuable feedback&lt;/em&gt;&lt;/p&gt;

&lt;h3 id='conclusion'&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Although these metrics aren&amp;#8217;t 100% accurate (see &lt;a href='http://code.google.com/speed/articles/web-metrics.html'&gt;&lt;strong&gt;Caveats section&lt;/strong&gt;&lt;/a&gt; on Google&amp;#8217;s article) it&amp;#8217;s a good resource to compare your site with a sample of several billion pages crawled by Googlebot. Have fun!&lt;/p&gt;

&lt;p&gt;WARNING: Like &lt;a href='http://jslint.com/'&gt;JSLint&lt;/a&gt;, Web Metrics Framework might hurt your feelings :-)&lt;/p&gt;

&lt;p&gt;DISCLAIMER: This extension is not related with Google Inc. or Yahoo! Inc.&lt;/p&gt;</content>
    </entry>
    
    
    
    
    
    
    
    
    
    
    <entry>
        <title>New posts about performance. Back and alive!</title>
        <link href="http://javascriptrules.com/2010/04/27/new-posts-about-performance-back-and-alive"/>
        <updated>2010-04-27T00:00:00-07:00</updated>
        <id>/2010/04/27/new-posts-about-performance-back-and-alive</id>
        <content type="html">&lt;p&gt;After a long period of no posts due to personal issues, I&amp;#8217;m back now and alive!&lt;br /&gt;This time with a new post on &lt;a href='http://developer.yahoo.net/blog/'&gt;YDN&lt;/a&gt; - Yahoo! Developer Network - blog: &lt;a href='http://developer.yahoo.net/blog/archives/2010/04/performance_on_yahoo_search_earth_day_data_uri_ftw.html'&gt;Performance on Yahoo! Search for Earth Day&lt;/a&gt;.&lt;br /&gt;In this post I describe the performance case study of &lt;a href='http://search.yahoo.com/'&gt;Yahoo! Search&lt;/a&gt; &lt;a href='http://events.yahoo.com/earthday/2010/'&gt;Earth Day campaign&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;During this long off-post period, besides my day job, I&amp;#8217;ve been doing some experiments, developing some tools and brainstorming lots of ideas, mostly related to performance and JavaScript. I do have some post drafts and will be publishing them soon. Here are a few topics I&amp;#8217;m covering along this year:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;setTimeout minimum delay limit&lt;/li&gt;

&lt;li&gt;Prefetching CSS images&lt;/li&gt;

&lt;li&gt;Problems with gradients filters on IE links hover&lt;/li&gt;

&lt;li&gt;Flipping page direction RTL/LTR easily - &lt;a href='https://addons.mozilla.org/en-US/firefox/addon/114416'&gt;RTLzr&lt;/a&gt; a Firefox extension&lt;/li&gt;

&lt;li&gt;JavaScript Interviews Exposed (series)&lt;/li&gt;

&lt;li&gt;Lazy Enhancement&lt;/li&gt;

&lt;li&gt;JavaScript video subtitle&lt;/li&gt;

&lt;li&gt;JavaScript video timeline marks&lt;/li&gt;

&lt;li&gt;Deleting a removed node from DOM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned!&lt;/p&gt;</content>
    </entry>
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    <entry>
        <title>Fast min/max in arrays</title>
        <link href="http://javascriptrules.com/2009/09/23/fast-minmax-in-arrays"/>
        <updated>2009-09-23T00:00:00-07:00</updated>
        <id>/2009/09/23/fast-minmax-in-arrays</id>
        <content type="html">&lt;p&gt;This morning while commuting to the office, reading &lt;a href='http://www.javascriptrules.com/books/#nicholaszakas-professionaljavascript'&gt;JavaScript for Web Developers&lt;/a&gt;, I bumped into a question: how could I improve a well known algorithm that gets the smallest or the largest number in an array by using built-in Math methods such as &lt;a href='https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Math/min'&gt;Math.min&lt;/a&gt; and &lt;a href='https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Math/max'&gt;Math.max&lt;/a&gt;. For those not familiar with these methods, they return the smallest or the largest number respectively from a list of zero or more numbers passed as parameters, e.g.: &lt;code&gt;Math.min(4,3,9,6)&lt;/code&gt; returns 3, &lt;code&gt;Math.max(4,3,9,6)&lt;/code&gt; returns 9. I was wondering if calling such methods using &lt;code&gt;apply&lt;/code&gt; and an &lt;code&gt;Array&lt;/code&gt; as argument would work. I could hardly wait to get to the office to test it out on my &lt;a href='http://getfirebug.com/'&gt;Firebug&lt;/a&gt; console. I first tried:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nb'&gt;Math&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;apply&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;Math&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And bingo! It works!&lt;/p&gt;

&lt;h3 id='previous_work'&gt;Previous work&lt;/h3&gt;

&lt;p&gt;Since it seemed so easy I thought that somebody else would had already figured this out before and I did a &lt;a href='http://search.yahoo.com/search?p=Math.max.apply'&gt;quick search&lt;/a&gt; for &lt;code&gt;Math.max.apply&lt;/code&gt; and *bam!*: the first occurrence was a &lt;a href='http://ejohn.org/blog/fast-javascript-maxmin/'&gt;John Resig&amp;#8217;s post&lt;/a&gt; back in 07&amp;#8217;s where he describes such technique for augmenting &lt;code&gt;Array&lt;/code&gt; type. Really handy.&lt;/p&gt;

&lt;h3 id='performance'&gt;Performance&lt;/h3&gt;

&lt;p&gt;My main concern to decide whether to use this technique was its performance, so I ran a quick test comparing it to a very popular &lt;code&gt;for&lt;/code&gt; loop algorithm and an optimized loop for a given array of random numbers:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[],&lt;/span&gt;
    &lt;span class='nx'&gt;len&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='nx'&gt;e4&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='cm'&gt;/* create an array of ten thousand random numbers */&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;time&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;array creation&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='nx'&gt;lt&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;len&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;Math&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;floor&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;Math&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;random&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='nx'&gt;e4&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;timeEnd&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;array creation&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='cm'&gt;/* for loop */&lt;/span&gt;
&lt;span class='nx'&gt;max&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='kc'&gt;Infinity&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;time&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;for loop&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='nx'&gt;lt&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;len&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nx'&gt;max&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;timeEnd&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;for loop&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='cm'&gt;/* optimized loop */&lt;/span&gt;
&lt;span class='nx'&gt;max&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='kc'&gt;Infinity&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;len&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;time&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;optimized loop&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='k'&gt;while&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;--&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nx'&gt;max&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;timeEnd&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;optimized loop&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='cm'&gt;/* Math.max */&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;time&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Math.max&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='nx'&gt;max&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;Math&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;apply&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;Math&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;timeEnd&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Math.max&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Running this code on my firebug console (Firefox 3.0.14), I got the same largest number on each technique within the array as expected and the following times:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;array creation: &lt;strong&gt;89ms&lt;/strong&gt;&lt;/li&gt;

&lt;li&gt;for loop: &lt;strong&gt;29ms&lt;/strong&gt;&lt;/li&gt;

&lt;li&gt;optimized loop: &lt;strong&gt;20ms&lt;/strong&gt;&lt;/li&gt;

&lt;li&gt;Math.max: &lt;strong&gt;1ms&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wow! This is pretty fast! Huh? You can copy the code above and paste on your firebug console in order to get your own results or you can &lt;a href='http://sandbox.javascriptrules.com/fastminmax/'&gt;check it out here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='conclusion'&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;This technique deserves lots of credit for its simplicity and speed, it&amp;#8217;s those one-line codes that beats any fancy and complex algorithm that once you get to know, you start using every time you need, however it&amp;#8217;s not true for all browsers :-(&lt;/p&gt;</content>
    </entry>
    
    
    
    
    
    
    
    
    
    
    <entry>
        <title>WebKit Page Cache</title>
        <link href="http://javascriptrules.com/2009/09/17/webkit-page-cache"/>
        <updated>2009-09-17T00:00:00-07:00</updated>
        <id>/2009/09/17/webkit-page-cache</id>
        <content type="html">&lt;p&gt;Performance on the web has always been a hot topic to talk about specially when you talk about page load, but you don&amp;#8217;t see as often people talking about perceived load which is related to how fast the interface responds to the user interaction, in this area &lt;a href='http://en.wikipedia.org/wiki/WebKit#Browser_version_summary'&gt;WebKit based browsers&lt;/a&gt; like Safari and Chrome from my point of view have always been ahead.&lt;/p&gt;

&lt;p&gt;In the article &lt;a href='http://webkit.org/blog/427/webkit-page-cache-i-the-basics/'&gt;WebKit Page Cache I - The Basics&lt;/a&gt; Brady Eidson talks about the Page Cache feature on WebKit, as he stated it&amp;#8217;s not about caching in the HTTP sense, storing raw files on disk or even caching resources in memory. &amp;#8220;More simply, when you leave the page we &lt;em&gt;pause&lt;/em&gt; it and when you come back we press &lt;em&gt;play&lt;/em&gt;.&amp;#8221;, this totally affects the perceived performance, when you hit the back button, even if you have files cached locally the browser will still have to load it again, run all your scripts, recreate the DOM and so on, so basically &amp;#8220;When the Page Cache works it makes clicking the back button almost instantaneous.&amp;#8221;&lt;/p&gt;

&lt;p&gt;The last time they updated Page Cache was back in &amp;#8216;02 the web has evolved a lot since then and it&amp;#8217;s not easy to keep up to date, you have to take in considetration HTTPS, plugins, frames, page events, although some of these issues have been fixed already like the frames problem, it still a long way to go, anyway it&amp;#8217;s great to see that they are working on it.&lt;/p&gt;</content>
    </entry>
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    <entry>
        <title>String searching algorithms in JavaScript engines</title>
        <link href="http://javascriptrules.com/2009/08/12/string-searching-algorithms-in-javascript-engines"/>
        <updated>2009-08-12T00:00:00-07:00</updated>
        <id>/2009/08/12/string-searching-algorithms-in-javascript-engines</id>
        <content type="html">&lt;p&gt;I&amp;#8217;ve just finished chapter 7: Writing Efficient JavaScript by &lt;a href='http://www.nczonline.net/'&gt;Nicholas Zakas&lt;/a&gt; on &lt;a href='http://stevesouders.com/'&gt;Steve Souders&lt;/a&gt;&amp;#8217; new book, &lt;a href='http://www.javascriptrules.com/books/#stevesouders-evenfaster'&gt;Even Faster Web Sites&lt;/a&gt;, where he presents several string optimization techniques to improve JavaScript performance and wondered which algorithm does &lt;code&gt;String.indexOf&lt;/code&gt; method implements on &lt;a href='http://en.wikipedia.org/wiki/JavaScript_engine'&gt;JavaScript engines&lt;/a&gt; (aka &lt;a href='http://en.wikipedia.org/wiki/List_of_ECMAScript_engines'&gt;ECMAScript engines&lt;/a&gt;).&lt;br /&gt;A few months ago I&amp;#8217;ve asked this question to Yahoo! fellow &lt;a href='http://crockford.com/'&gt;Douglas Crockford&lt;/a&gt; and he said the ECMAScript standard does not require a specific algorithm, so it could vary with each browser. You can check that on section 15.5.4.7 of &lt;a href='http://www.ecma-international.org/publications/standards/Ecma-262.htm'&gt;Standard ECMA-262&lt;/a&gt;. I decided then to download the most popular open-source JavaScript engines source codes and found mainly 3 algorithms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/String_searching_algorithm#Na.C3.AFve_string_search'&gt;Naïve&lt;/a&gt;: simple and least inefficient way to search in strings, it basically checks every position in the haystack then every position of the needle. The advantage of using this algorithm is that it needs no initial overhead such as auxiliary tables creation. It has O(mn) complexity, where m is the needle length and n the haystack length.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Boyer_moore'&gt;Boyer-Moore&lt;/a&gt;: Efficient searching string algorithm that preprocesses the needle and doesn&amp;#8217;t check every position in the haystack but rather skips some of them on each unsuccessful attempt. It has O(n) complexity with O(3n) in the worst case.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Boyer-Moore-Horspool_algorithm'&gt;Boyer-Moore-Horspool&lt;/a&gt;: It&amp;#8217;s a simplification of Boyer-Moore&amp;#8217;s algorithm with less overhear during initial needle preprocessing. It also has O(n) complexity but O(mn) in the worst case.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='algorithms_by_engines'&gt;Algorithms by engines&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;String.indexOf&lt;/code&gt; algorithms by JavaScript engines follows:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;JavaScript Engine&lt;/th&gt;&lt;th&gt;Layout Engine&lt;/th&gt;&lt;th&gt;Browsers&lt;/th&gt;&lt;th&gt;String.indexOf algorithm&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='https://developer.mozilla.org/en/SpiderMonkey'&gt;SpiderMonkey&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://www.mozilla.org/newlayout/'&gt;Gecko&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Firefox up to 3.0.*&lt;/td&gt;&lt;td style='text-align: left;'&gt;Boyer-Moore-Horspool&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='https://wiki.mozilla.org/JavaScript:TraceMonkey'&gt;TraceMonkey&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://www.mozilla.org/newlayout/'&gt;Gecko&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Firefox from 3.1.*&lt;/td&gt;&lt;td style='text-align: left;'&gt;Boyer-Moore-Horspool&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://api.kde.org/4.0-api/kdelibs-apidocs/kjs/html/index.html'&gt;KJS&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://www.konqueror.org/features/browser.php'&gt;KHTML&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Konqueror&lt;/td&gt;&lt;td style='text-align: left;'&gt;Naïve&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://webkit.org/projects/javascript/'&gt;JavaScriptCore&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://webkit.org/'&gt;WebKit&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Safari up to 3.*&lt;/td&gt;&lt;td style='text-align: left;'&gt;Naïve&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://trac.webkit.org/wiki/SquirrelFish'&gt;SquirrelFish&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://webkit.org/'&gt;WebKit&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Safari from 4.*&lt;/td&gt;&lt;td style='text-align: left;'&gt;Naïve&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://msdn.microsoft.com/en-us/library/hbxc2t98(VS.85).aspx'&gt;JScript&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://msdn.microsoft.com/en-us/library/aa741317(VS.85).aspx'&gt;Trident&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Internet Explorer&lt;/td&gt;&lt;td style='text-align: left;'&gt;?&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://code.google.com/p/v8/'&gt;V8&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://webkit.org/'&gt;WebKit&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Chrome&lt;/td&gt;&lt;td style='text-align: left;'&gt;Strategy: Naïve, Boyer-Moore-Horspool and Boyer-Moore&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Linear B&lt;/td&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://en.wikipedia.org/wiki/Presto_(layout_engine)'&gt;Presto&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Opera 7.0 - 9.50[&lt;/td&gt;&lt;td style='text-align: left;'&gt;?&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Futhark&lt;/td&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://dev.opera.com/articles/view/presto-2-2-and-opera-10-a-first-look/'&gt;Presto Core 2&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Opera from 9.50&lt;/td&gt;&lt;td style='text-align: left;'&gt;?&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://www.mozilla.org/rhino/'&gt;Rhino&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;-&lt;/td&gt;&lt;td style='text-align: left;'&gt;-&lt;/td&gt;&lt;td style='text-align: left;'&gt;java.lang.String.indexOf&lt;/td&gt;
&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h4 id='spidermonkey'&gt;SpiderMonkey&lt;/h4&gt;

&lt;p&gt;Implements the &lt;code&gt;String.indexOf&lt;/code&gt; in C with some verifications in string lengths prior to run BMH algorithm in order to avoid long searching for relatively small strings.&lt;/p&gt;

&lt;p&gt;Source code available at: &lt;a href='ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/3.0.13/source/firefox-3.0.13-source.tar.bz2'&gt;ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/3.0.13/source/firefox-3.0.13-source.tar.bz2&lt;/a&gt;&lt;/p&gt;

&lt;h4 id='tracemonkey'&gt;TraceMonkey&lt;/h4&gt;

&lt;p&gt;It has exactly the same &lt;code&gt;String.indexOf&lt;/code&gt; implementation as SpiderMonkey but in C++.&lt;/p&gt;

&lt;p&gt;Source code available at: &lt;a href='ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/3.5.2/source/firefox-3.5.2-source.tar.bz2'&gt;ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/3.5.2/source/firefox-3.5.2-source.tar.bz2&lt;/a&gt;&lt;/p&gt;

&lt;h4 id='kjs'&gt;KJS&lt;/h4&gt;

&lt;p&gt;The main part of the naïve implementation of &lt;code&gt;indexOf&lt;/code&gt; follows*:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='cpp'&gt;&lt;span class='cm'&gt;/* ... */&lt;/span&gt;
&lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;const&lt;/span&gt; &lt;span class='n'&gt;UChar&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;data_&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;pos&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;lt&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='o'&gt;++&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;uc&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='n'&gt;fchar&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;memcmp&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;c&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;fdata&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;fsizeminusone&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
        &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;c&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;data_&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;* taken from KDE 4.0 API reference&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Files related to &lt;code&gt;String.indexOf&lt;/code&gt; method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;string_object.cpp: defines the prototype for String object where &lt;code&gt;indexOf&lt;/code&gt; is in a switch case statement and calls &lt;code&gt;find&lt;/code&gt; function.&lt;/li&gt;

&lt;li&gt;ustring.cpp: defines the &lt;code&gt;find&lt;/code&gt; function where the naïve algorithm is implemented.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Browse the source code online: &lt;a href='http://api.kde.org/4.0-api/kdelibs-apidocs/kjs/html/files.html'&gt;http://api.kde.org/4.0-api/kdelibs-apidocs/kjs/html/files.html&lt;/a&gt;&lt;/p&gt;

&lt;h4 id='javascriptcore__squirrelfish'&gt;JavaScriptCore &amp;amp; SquirrelFish&lt;/h4&gt;

&lt;p&gt;These engines are known as JavaScriptCore in WebKit Project and was originally derived from KJS, hence still shares the same algorithm for &lt;code&gt;String.indexOf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Files related to &lt;code&gt;String.indexOf&lt;/code&gt; method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;root/trunk/JavaScriptCore/runtime/StringPrototype.cpp: this is where &lt;code&gt;indexOf&lt;/code&gt; method is defined and call &lt;code&gt;find&lt;/code&gt; function&lt;/li&gt;

&lt;li&gt;root/trunk/JavaScriptCore/runtime/UString.cpp: look for &lt;code&gt;find&lt;/code&gt; function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source code available at: &lt;a href='http://webkit.org/building/checkout.html'&gt;http://webkit.org/building/checkout.html&lt;/a&gt;&lt;br /&gt;Browse the source code online: &lt;a href='http://trac.webkit.org/browser'&gt;http://trac.webkit.org/browser&lt;/a&gt;&lt;/p&gt;

&lt;h4 id='v8'&gt;V8&lt;/h4&gt;

&lt;p&gt;A very smart strategy is applied to the string searching in order to choose the best algorithm based on the length of the needle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First of all it checks if there is a non-ASCII needle for an ASCII haystack and bail out if there is.&lt;/li&gt;

&lt;li&gt;Checks if the needle length is less than 5 then uses a naïve solution called &lt;code&gt;simpleIndexOf&lt;/code&gt;, because the max shift of Boyer-Moore on such needle length doesn&amp;#8217;t compensate for the overhead. This &lt;code&gt;simpleIndexOf&lt;/code&gt; function never bails out, it means that the needle will be checked for a match in the whole haystack.&lt;/li&gt;

&lt;li&gt;If the needle length is greater than or equals to 5 another &lt;code&gt;simpleIndexOf&lt;/code&gt; function is called. This one considers how much work have been done (unsuccessful matches) in order to stop trying and switch for a better algorithm. This is called the &amp;#8220;badness count&amp;#8221; which once reached the max, stop the search and returns the index in the haystack where the next algorithm should continue from.&lt;/li&gt;

&lt;li&gt;The next algorithm in the strategy chain is Boyer-Moore-Horspool which also consider the badness count prior to jump to the next algorithm.&lt;/li&gt;

&lt;li&gt;The last one is Boyer-Moore which has some initial overhead when creating good and bad shift tables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source code available at: &lt;a href='http://code.google.com/p/v8/wiki/Source?tm=4'&gt;http://code.google.com/p/v8/wiki/Source?tm=4&lt;/a&gt;&lt;/p&gt;

&lt;h4 id='rhino'&gt;Rhino&lt;/h4&gt;

&lt;p&gt;Rhino runs on top of Java Virtual Machine and uses the &lt;code&gt;java.lang.String.indexOf&lt;/code&gt; from Java language implemented for such JVM. Interestingly there is a comment saying:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Uses Java String.indexOf(). OPT to add - BMH searching from jsstr.c&amp;#8221;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Where jsstr.c is the file for SpiderMonkey JavaScript String implementation. Implementing such algorithm in Java might degrade the search performance, unless the &lt;code&gt;java.lang.String.indexOf&lt;/code&gt; implementation is much worse than that.&lt;/p&gt;

&lt;p&gt;Source code available at: &lt;a href='http://www.mozilla.org/rhino/download.html'&gt;http://www.mozilla.org/rhino/download.html&lt;/a&gt;&lt;/p&gt;

&lt;h4 id='other_engines'&gt;Other engines&lt;/h4&gt;

&lt;p&gt;What about Internet Explorer, Opera and other browsers JavaScript engines? As they aren&amp;#8217;t open-source projects I could not check their codes out. :-(&lt;/p&gt;

&lt;h3 id='benchmark'&gt;Benchmark&lt;/h3&gt;

&lt;p&gt;By running a simple test across some browsers we can have an idea how fast/slow is &lt;code&gt;String.indexOf&lt;/code&gt; on some JavaScript engines although this doesn&amp;#8217;t necessarily mean an algorithm is better than another because the performance of the engine itself might affect the outcome.&lt;br /&gt;The test consists of the average of a 100 times running a search for the word &amp;#8221;&lt;em&gt;foobar&lt;/em&gt;&amp;#8221; in the middle of a ~1200 length &amp;#8221;&lt;em&gt;ipsum lorem&lt;/em&gt;&amp;#8221; text iterating 1 million times each search. &lt;a href='http://sandbox.javascriptrules.com/indexof/'&gt;Try it&lt;/a&gt; yourself.&lt;/p&gt;

&lt;p&gt;The results in the follow table were taken by running this test on the same machine (Pentium 4HT, 3GHz, 1Gb RAM, Windows XP SP3).&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;JavaScript Engine&lt;/th&gt;&lt;th&gt;Browser&lt;/th&gt;&lt;th&gt;Version&lt;/th&gt;&lt;th&gt;Average (ms)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;V8&lt;/td&gt;&lt;td style='text-align: left;'&gt;Chrome&lt;/td&gt;&lt;td style='text-align: left;'&gt;2.0.172.39&lt;/td&gt;&lt;td style='text-align: left;'&gt;827.66&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;SpiderMonkey&lt;/td&gt;&lt;td style='text-align: left;'&gt;Firefox&lt;/td&gt;&lt;td style='text-align: left;'&gt;3.0.13&lt;/td&gt;&lt;td style='text-align: left;'&gt;947.97&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;TraceMonkey&lt;/td&gt;&lt;td style='text-align: left;'&gt;Firefox&lt;/td&gt;&lt;td style='text-align: left;'&gt;3.5.2&lt;/td&gt;&lt;td style='text-align: left;'&gt;1169.25&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;SquirrelFish&lt;/td&gt;&lt;td style='text-align: left;'&gt;Safari&lt;/td&gt;&lt;td style='text-align: left;'&gt;4.0.2&lt;/td&gt;&lt;td style='text-align: left;'&gt;1207.02&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;KJS*&lt;/td&gt;&lt;td style='text-align: left;'&gt;Konqueror&lt;/td&gt;&lt;td style='text-align: left;'&gt;4.2.2&lt;/td&gt;&lt;td style='text-align: left;'&gt;1361.59&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;SpiderMonkey&lt;/td&gt;&lt;td style='text-align: left;'&gt;Firefox&lt;/td&gt;&lt;td style='text-align: left;'&gt;2.0.0.20&lt;/td&gt;&lt;td style='text-align: left;'&gt;1456.57&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Futhark&lt;/td&gt;&lt;td style='text-align: left;'&gt;Opera&lt;/td&gt;&lt;td style='text-align: left;'&gt;10.00 beta 2&lt;/td&gt;&lt;td style='text-align: left;'&gt;1549.06&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Futhark&lt;/td&gt;&lt;td style='text-align: left;'&gt;Opera&lt;/td&gt;&lt;td style='text-align: left;'&gt;9.64&lt;/td&gt;&lt;td style='text-align: left;'&gt;1613.02&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;JScript**&lt;/td&gt;&lt;td style='text-align: left;'&gt;Internet Explorer&lt;/td&gt;&lt;td style='text-align: left;'&gt;8.0&lt;/td&gt;&lt;td style='text-align: left;'&gt;3101.23&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Rhino***&lt;/td&gt;&lt;td style='text-align: left;'&gt;-&lt;/td&gt;&lt;td style='text-align: left;'&gt;-&lt;/td&gt;&lt;td style='text-align: left;'&gt;4103.64&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;JScript&lt;/td&gt;&lt;td style='text-align: left;'&gt;Internet Explorer&lt;/td&gt;&lt;td style='text-align: left;'&gt;6.0&lt;/td&gt;&lt;td style='text-align: left;'&gt;4479.82&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;JScript&lt;/td&gt;&lt;td style='text-align: left;'&gt;Internet Explorer&lt;/td&gt;&lt;td style='text-align: left;'&gt;7.0&lt;/td&gt;&lt;td style='text-align: left;'&gt;4515.08&lt;/td&gt;
&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;em&gt;* running on the same machine with Ubuntu 9.04 live cd&lt;/em&gt;&lt;br /&gt;&lt;em&gt;** running on a VM on a different computer&lt;/em&gt;&lt;br /&gt;&lt;em&gt;*** running on Sun JRE 6 - 1.6.0_14&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Again, these results don&amp;#8217;t prove which algorithm is the best due to different browser performances, however it is worth noting that Firefox 3.0.13 performed better than Firefox 3.5.2 on this benchmark. Internet Explorer had the worst results, it can be either the algorithm or the browser performance itself or even both. :-)&lt;/p&gt;</content>
    </entry>
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
 
</feed>

