<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
    <title>JavaScript Rules - ecma</title>
    <link href="http://javascriptrules.com/tag/ecma.xml" rel="self"/>
    <link href="http://javascriptrules.com"/>
    <updated>2012-03-08T18:28:28-08:00</updated>
    <id>http://javascriptrules.com/tag/ecma</id>
    <author>
        <name>Marcel Duran</name>
        <email>marcelduran@gmail.com</email>
    </author>
 
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    <entry>
        <title>JavaScript Challenge Revisited: Lotto Number Generator in Chains</title>
        <link href="http://javascriptrules.com/2009/10/06/javascript-challenge-revisited-lotto-number-generator-in-chains"/>
        <updated>2009-10-06T00:00:00-07:00</updated>
        <id>/2009/10/06/javascript-challenge-revisited-lotto-number-generator-in-chains</id>
        <content type="html">&lt;p&gt;Matthias Reuter from &lt;a href='http://www.united-coders.com/'&gt;United Coders&lt;/a&gt; proposed a &lt;a href='http://www.united-coders.com/matthias-reuter/javascript-challenge-lotto-number-generator'&gt;JavaScript Challenge: A Lotto Number Generator&lt;/a&gt; which the rules follow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Write a JavaScript function that generates random lotto numbers. This function has to return an array of six different numbers from 1 to 49 (including both) in ascending order. You may use features of &lt;a href='http://www.ecma-international.org/publications/standards/Ecma-262.htm'&gt;ECMA-262&lt;/a&gt; only, that means no Array.contains and stuff. You must not induce global variables. The function has to look like this&lt;/p&gt;
&lt;/blockquote&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;getRandomLottoNumbers&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;// your implementation here&lt;/span&gt;
&lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Minify your function using &lt;a href='http://javascript.crockford.com/jsmin.html'&gt;JSMin&lt;/a&gt; (level aggressive) and count the bytes between the outer curly braces.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It might look simple but it turns out to be an interesting challenge considering there&amp;#8217;s a bunch of ways to solve it where the length of the minified final implementation is the main concern: the smaller the better. He describes his solution and invites others to post their solutions as comments. His final solution for such challenge has 86 bytes:&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;n&lt;/span&gt;&lt;span class='o'&gt;=&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='k'&gt;for&lt;/span&gt;&lt;span class='p'&gt;(;&lt;/span&gt;&lt;span class='o'&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='mi'&gt;50&lt;/span&gt;&lt;span class='p'&gt;;)&lt;/span&gt;&lt;span class='nx'&gt;n&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;push&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='k'&gt;for&lt;/span&gt;&lt;span class='p'&gt;(;&lt;/span&gt;&lt;span class='o'&gt;--&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;;)&lt;/span&gt;&lt;span class='nx'&gt;n&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;splice&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='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;0&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='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Some readers wrote even smaller solutions such as:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;[,,,,,,].&lt;/span&gt;&lt;span class='nx'&gt;map&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&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;50&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;However this one is by far the smallest, 49 bytes only, it is invalid because it doesn&amp;#8217;t fulfill the rules for the following reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;map&lt;/code&gt; is not part of ECMA-262 specification&lt;/li&gt;

&lt;li&gt;&lt;code&gt;[,,,,,,]&lt;/code&gt; is inconsistent across browsers, IE would create an array of 7 &lt;code&gt;undefined&lt;/code&gt; values&lt;/li&gt;

&lt;li&gt;it&amp;#8217;s not in ascending order&lt;/li&gt;

&lt;li&gt;may contain duplicated values So far the smallest solution that fulfills all the rules has 65 bytes:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='k'&gt;for&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;v&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='p'&gt;[],&lt;/span&gt;&lt;span class='nx'&gt;m&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='nx'&gt;n&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='mi'&gt;49&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;&lt;span class='nx'&gt;m&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;&lt;span class='o'&gt;--&lt;/span&gt;&lt;span class='nx'&gt;n&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='nx'&gt;n&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt;&lt;span class='nx'&gt;m&lt;/span&gt;&lt;span class='o'&gt;?&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='nx'&gt;v&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='o'&gt;--&lt;/span&gt;&lt;span class='nx'&gt;m&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='nx'&gt;n&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;&lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='revisiting'&gt;Revisiting&lt;/h3&gt;

&lt;p&gt;I&amp;#8217;ve also contributed with my solution but with another fashion way: Using a single line chaining solution, i.e. no semi-colons separating statements, like: &lt;code&gt;return a().b.c().d.e()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;My solution has 200 bytes:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&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;join&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;replace&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/0/g&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(){&lt;/span&gt;&lt;span class='nb'&gt;Array&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='nb'&gt;Array&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='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;x&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;x&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;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;50&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='k'&gt;in&lt;/span&gt; &lt;span class='nb'&gt;Array&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='nb'&gt;Array&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;x&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='p'&gt;;&lt;/span&gt;&lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;}).&lt;/span&gt;&lt;span class='nx'&gt;split&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;sort&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&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;b&lt;/span&gt;&lt;span class='p'&gt;){&lt;/span&gt;&lt;span class='k'&gt;delete&lt;/span&gt; &lt;span class='nb'&gt;Array&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='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='nx'&gt;b&lt;/span&gt;&lt;span class='p'&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s not the smallest compared to the other solutions but it does fulfill the rules and is in a single line chaining. It might be a little obscure for some but I will break it down into smaller peaces:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='k'&gt;return&lt;/span&gt;
    &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;   &lt;span class='c1'&gt;// creates an array with 6 positions filled with 0&amp;#39;s&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;join&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;         &lt;span class='c1'&gt;// converts the array into string: &amp;quot;0,0,0,0,0,0&amp;quot;&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;replace&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/0/g&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='c1'&gt;// replaces all 0&amp;#39;s in the string using the following function&lt;/span&gt;
        &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='nb'&gt;Array&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='nb'&gt;Array&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='c1'&gt;// augments Array with an object property only once&lt;/span&gt;
            &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;                          &lt;span class='c1'&gt;// variable to store a random number&lt;/span&gt;
            &lt;span class='k'&gt;while&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;                         &lt;span class='c1'&gt;// while condition: assures no dupes&lt;/span&gt;
                &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;                        &lt;span class='c1'&gt;// assigning a value to x:&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;50&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;  &lt;span class='c1'&gt;// generates a random number times 50 or 1 (when 0)&lt;/span&gt;
                &lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt; &lt;span class='nb'&gt;Array&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;                &lt;span class='c1'&gt;// checks if x isn&amp;#39;t in the augmented Array object&lt;/span&gt;
            &lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;                            &lt;span class='c1'&gt;// empty block for while statement&lt;/span&gt;
            &lt;span class='nb'&gt;Array&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;x&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='p'&gt;;&lt;/span&gt;                 &lt;span class='c1'&gt;// adds number as property into Array object&lt;/span&gt;
            &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt;                        &lt;span class='c1'&gt;// replaces the &amp;quot;0&amp;quot; found by the random x number&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;)&lt;/span&gt;               &lt;span class='c1'&gt;// end of replace function&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;split&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;     &lt;span class='c1'&gt;// converts string into array of strings using comma as separator&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;sort&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;          &lt;span class='c1'&gt;// sorts the array using the following compare function&lt;/span&gt;
        &lt;span class='kd'&gt;function&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;b&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;   &lt;span class='c1'&gt;// elements to be compared&lt;/span&gt;
            &lt;span class='k'&gt;delete&lt;/span&gt; &lt;span class='nb'&gt;Array&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='c1'&gt;// restores Array, removing previously augmented property&lt;/span&gt;
            &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='nx'&gt;b&lt;/span&gt;    &lt;span class='c1'&gt;// &amp;amp;lt; 0 then a &amp;amp;lt; b; = 0 then a = b; &amp;gt; 0 a &amp;gt; b&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;)&lt;/span&gt;               &lt;span class='c1'&gt;// end of sort, a sorted array is returned&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I also invite you to post your single line chaining solution as a comment. Happy chaining. ;-)&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>

