<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog &#124; BenHollis.net &#187; Web</title>
	<atom:link href="http://benhollis.net/blog/category/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://benhollis.net/blog</link>
	<description>News about BenHollis.net and articles about Ben&#039;s interests</description>
	<lastBuildDate>Fri, 04 Jun 2010 05:39:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Searchable tab switching in Firefox 3.6</title>
		<link>http://benhollis.net/blog/2010/01/31/searchable-tab-switching-in-firefox-3-6/</link>
		<comments>http://benhollis.net/blog/2010/01/31/searchable-tab-switching-in-firefox-3-6/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 02:02:59 +0000</pubDate>
		<dc:creator>Ben Hollis</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[iswitchb]]></category>
		<category><![CDATA[tabs]]></category>

		<guid isPermaLink="false">http://benhollis.net/blog/?p=466</guid>
		<description><![CDATA[As an emacs user, I&#8217;ve found iswitchb (interactive-switch-buffers) to be a huge time saver. Basically, to switch files (buffers) you enter a typically byzantine key combination and then type to search through your open files &#8211; as less and less files match your search, the choices narrow down, and you can choose between them. This [...]]]></description>
			<content:encoded><![CDATA[<p>As an <a href="http://www.gnu.org/software/emacs/">emacs</a> user, I&#8217;ve found <a href="http://www.emacswiki.org/emacs/IswitchBuffers">iswitchb</a> (interactive-switch-buffers) to be a huge time saver. Basically, to switch files (buffers) you enter a typically byzantine key combination and then type to search through your open files &#8211; as less and less files match your search, the choices narrow down, and you can choose between them. This ends up being way faster than switching with a mouse even in tabbed editors, and I&#8217;ve managed to set up a similar thing in Eclipse/Aptana. But until recently I didn&#8217;t have the same functionality for switching tabs in Firefox.</p>
<p>The good news is that Firefox 3.6 has this feature built in, though it takes a bit of work to enable. Apparently <a href="http://jboriss.wordpress.com/2008/07/16/control-tab-a-new-feature-for-firefox/">they&#8217;ve been trying to get this feature into Firefox since 3.0</a>, but there&#8217;s been a lot of different opinions, so even though they finally shipped it with 3.6, it isn&#8217;t on by default. You can turn it on by going to <b>about:config</b> (just type that right into your address bar), then searching for &#8220;ctrlTab&#8221;. Double-click <b>browser.ctrlTab.previews</b> to turn it to &#8220;true&#8221;. Now, when you hit Ctrl-Tab, you&#8217;ll get a tab switcher that looks a bit like the default Windows Alt-Tab window switcher (though with a much lighter glass effect that honestly looks pretty bad compared to Windows&#8217; Alt-Tab). On other platforms you&#8217;ll get a similarly system-integrated look. Unfortunately this popup isn&#8217;t exactly what we&#8217;re looking for &#8211; it doesn&#8217;t show all your tabs and you can&#8217;t search! However, you can navigate down to &#8220;show all X tabs&#8221; at the bottom and you get a search box and a list of every tab. That&#8217;s a real pain to do every time you want to switch tabs, though. Fortunately, there&#8217;s a solution. Instead of hitting Ctrl-Tab, use Ctrl-Shift-Tab, and you&#8217;ll start out right at the big tab switcher with search. From here you can type to narrow down your selection and hit Enter to choose your tab. I wish there was a preference to make this full search show up when you hit Ctrl-Tab, but it doesn&#8217;t look like there is.</p>
<p class="blogimage"><a href="http://benhollis.net/blog/wp-content/uploads/2010/01/ff_ctrlTab.jpg"><img src="http://benhollis.net/blog/wp-content/uploads/2010/01/ff_ctrlTab-400x169.jpg" alt="Firefox Ctrl-Shift-Tab tab switcher" title="Firefox Ctrl-Shift-Tab tab switcher" width="400" height="169" /></a><br />
<em>Switching between tabs (man, that glass effect is a mess)</b></em></p>
<p>Visual issues aside, I wish every program with a tab-oriented UI had a feature like this to make their app faster to use for keyboard users. While we&#8217;re at it, Windows and OSX should add search to their built-in window switchers &#8211; it could really help when I have a lot of windows open and don&#8217;t want to reach for the mouse.</p>
<p>Note: There are a couple extensions for Google Chrome that theoretically give a similar searchable tab switcher, but of the few I tried, none of them could appear with a keyboard shortcut &#8211; you had to click an icon on the toolbar, which seems to defeat the point. Apparently the Chrome Extensions API has known problems with keyboard shortcuts, so maybe things will get better soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://benhollis.net/blog/2010/01/31/searchable-tab-switching-in-firefox-3-6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Simple expiring caching for Ruby on Rails</title>
		<link>http://benhollis.net/blog/2010/01/30/simple-expiring-caching-for-ruby-on-rails/</link>
		<comments>http://benhollis.net/blog/2010/01/30/simple-expiring-caching-for-ruby-on-rails/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 02:48:35 +0000</pubDate>
		<dc:creator>Ben Hollis</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://brh.numbera.com/blog/?p=367</guid>
		<description><![CDATA[Ruby on Rails has some great caching support built right in, but it&#8217;s most useful when you have MemCacheD or DRb around to serve as a cache store. I don&#8217;t have access to those everywhere &#8211; Dreamhost and other shared hosting providers often prohibit running your own MemCacheD. There&#8217;s a default memory store, but it [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby on Rails has some <a href="http://guides.rails.info/caching_with_rails.html">great caching support</a> built right in, but it&#8217;s most useful when you have MemCacheD or DRb around to serve as a cache store. I don&#8217;t have access to those everywhere &#8211; Dreamhost and other shared hosting providers often prohibit running your own MemCacheD. There&#8217;s a default memory store, but it won&#8217;t share cached info between Rails server processes. That leaves the file store, which just writes cached objects to a file that gets shared between all your Rails processes on the same box. The main problem with the file store is that it doesn&#8217;t support time-based expiration &#8211; you have to set up a <tt>cron</tt> job to sweep out the cache files every once in a while to invalidate your cache.</p>
<p>To get around this, I wrote a tiny, obvious little module that gives a simple syntax for caching objects with the file store. The trick is that it stores the insert time whenever it caches a new object, and compares it with the current time every time it looks it up. If the cached object is too old (or the cache is empty), it throws it away and executes the provided block and caches the new value.</p>
<p><script src="http://gist.github.com/290848.js?file=simple_cache.rb"></script></p>
<p>Be sure to use the same expiration whenever you <tt>fetch</tt> the same object, or things will expire differently depending on where they&#8217;re accessed. You can also do a bit of customization for more complex cache invalidations &#8211; I have a version of <tt>fetch</tt> that caches objects within one calendar day and recalculates them only when the date is different. I suppose I could made <tt>fetch</tt> take an optional <tt>Proc</tt> to control the caching strategy, but I didn&#8217;t really need that much customization. Anyway, this isn&#8217;t exactly brilliant new code, but it has made caching objects from my smaller Rails apps a bit easier.</p>
]]></content:encoded>
			<wfw:commentRss>http://benhollis.net/blog/2010/01/30/simple-expiring-caching-for-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Speeding up jQuery&#8217;s each function</title>
		<link>http://benhollis.net/blog/2010/01/23/speeding-up-jquerys-each-function/</link>
		<comments>http://benhollis.net/blog/2010/01/23/speeding-up-jquerys-each-function/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 01:52:11 +0000</pubDate>
		<dc:creator>Ben Hollis</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://benhollis.net/blog/?p=413</guid>
		<description><![CDATA[In my previous post, &#8220;Investigating JavaScript Array Iteration Performance&#8220;, I found that among a selection of different array iteration methods, jQuery&#8217;s each function was the slowest. It&#8217;s worth mentioning again that these investigations are pretty academic &#8211; array iteration and looping speed is unlikely to be the source of performance problems compared to actual program [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous post, &#8220;<a href="/blog/2009/12/13/investigating-javascript-array-iteration-performance/">Investigating JavaScript Array Iteration Performance</a>&#8220;, I found that among a selection of different array iteration methods, jQuery&#8217;s <tt>each</tt> function was the slowest. It&#8217;s worth mentioning again that these investigations are pretty academic &#8211; array iteration and looping speed is unlikely to be the source of performance problems compared to actual program logic, DOM manipulation, string manipulation, etc. I just found it interesting to poke into how things work in different browsers. That said, with the recent release of jQuery 1.4 emphasizing performance so much, I wanted to see what if anything could be done to speed up <tt>each</tt> (which is used inside jQuery all over the place), and whether it would made much of a difference.</p>
<p>Again, the details are after the jump.<br />
<span id="more-413"></span></p>
<p>For reference, here&#8217;s the original implementation of jQuery.each from jQuery 1.3.2 (it hasn&#8217;t changed much for 1.4):</p>
<pre>
function( object, callback, args ) {
 var name, i = 0, length = object.length;

 if ( args ) {
  ... omitted ...

 } else {
  if ( length === undefined ) {
    ... omitted ...
  } else
   <span style="color: green">for ( var value = object[0];
    i < length &#038;&#038; callback.call( value, i, value ) !== false; value = object[++i] ){}</span>
 }

 return object;
}
</pre>
<p>I cut out some pieces relating to iterating over Objects instead of Arrays, and some internal-only code, just for brevity. You can see that at its core, <tt>each</tt> just iterates over the array with a regular <tt>for</tt> loop and calls the provided callback for each element. It&#8217;s using the <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Function/call"><tt>call</tt></a> function to invoke the callback so it can set <tt>this</tt> to the value of each element in the array in turn, and passes the index in the array and the value at that index as parameters to the callback as well.</p>
<p>I ended up trying four different modifications of jQuery&#8217;s <tt>each</tt> function. I also allowed myself to actually change the signature of <tt>each</tt>, which would likely break much existing code written on top of jQuery, but it gave me a lot more freedom to tweak things.</p>
<p>The first was to try using native <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach"><tt>Array.forEach</tt></a> (where available). I had to pass in my own callback to <tt>forEach</tt> that reversed the order of the index and value arguments to the function, since <tt>jQuery.each</tt> and <tt>Array.forEach</tt> put those arguments in opposite order. Of course, I had to fall back on the original <tt>for</tt> loop implementation for IE. This modification retains the complete behavior from the original implementation.</p>
<pre>
<span style="color: green">if (jQuery.isFunction(object.forEach) ) {
  object.forEach(function(value, i) {
    callback.call(value, i, value);
  });
}</span>
else {
  for (var value = object[0];
    i < length &#038;&#038; callback.call(value, i, value) !== false;
    value = object[++i]) {}
}
</pre>
<p>Next, I tried skipping the callback that switches the order of arguments and just passing the user's callback directly to <tt>forEach</tt>. I had to modify the fallback to match this. Notice in both cases we no longer set <tt>this</tt> to the current element in the iteration - <tt>Array.forEach</tt> doesn't support that directly. We're solidly in non-backwards-compatible change territory here.</p>
<pre>
if (jQuery.isFunction(object.forEach) ) {
  <span style="color: green">object.forEach(callback);</span>
}
else {
  for (var value = object[0];
    i < length &#038;&#038; <span style="color: green">callback.call(null, value, i)</span> !== false;
    value = object[++i]) {}
}
</pre>
<p>I noticed in testing this out that Firefox seems to really struggle with using <tt>call</tt> with a frequently-changing value for <tt>this</tt> (the first parameter) so I tried another variation that didn't use native <tt>Array.forEach</tt> but just didn't change <tt>this</tt> in the <tt>call</tt> (I let it be the whole array each time):</p>
<pre>
for (var value = object[0];
  i < length &#038;&#038; callback.call(object, i, value) !== false;
  value = object[++i]) {}
</pre>
<p>After that, I wondered why use <tt>call</tt> at all (I might be missing something important here about how JavaScript function invocation works - please correct me!) So I tried a version that just called the callback directly.</p>
<pre>
for (var value = object[0];
  i < length &#038;&#038;  <span style="color: green">callback(i, value)</span> !== false;
  value = object[++i]) {}
</pre>
<p>With these four variations, I went and tested how long it took for them to iterate over a 500,000 element array in different browsers. In the previous tests I used 100,000 elements but the tests completed too fast to get meaningful results (which should tell you how fast this stuff is to begin with!). As in the previous post, the absolute numbers don't really mean much - it's the comparison between the different approaches that matters.</p>
<table class="datatable numbers">
<caption>Time to iterate over an array of 500,000 integers</caption>
<tr>
<th></th>
<th><tt>jQuery.each</tt></th>
<th><tt>Array.forEach</tt> (same signature as jQuery)</th>
<th><tt>Array.forEach</tt> (native signature)</th>
<th>Unvarying '<tt>this</tt>'</th>
<th>No <tt>call</tt></th>
</tr>
<tr>
<th>Firefox 3.5</th>
<td>1,358ms</td>
<td>1,591ms</td>
<td>371ms</td>
<td>576ms</td>
<td>469ms</td>
</tr>
<tr>
<th>Firefox 3.6rc2</th>
<td>546ms</td>
<td>672ms</td>
<td>201ms</td>
<td>194ms</td>
<td>109ms</td>
</tr>
<tr>
<th>Firefox 3.7a1pre</th>
<td>524ms</td>
<td>641ms</td>
<td>173ms</td>
<td>102ms</td>
<td>301ms</td>
</tr>
<tr>
<th>Chrome 3</th>
<td>81ms</td>
<td>94ms</td>
<td>41ms</td>
<td>38ms</td>
<td>35ms</td>
</tr>
<tr>
<th>Safari 4</th>
<td>54ms</td>
<td>102ms</td>
<td>102ms</td>
<td>69ms</td>
<td>56ms</td>
</tr>
<tr>
<th>IE 8</th>
<td>789ms</td>
<td>759ms</td>
<td>693ms</td>
<td>741ms</td>
<td>476ms</td>
</tr>
<tr>
<th>Opera 10.10</th>
<td>451ms</td>
<td>703ms</td>
<td>286ms</td>
<td>305ms</td>
<td>228ms</td>
</tr>
</table>
<p>We find that Firefox 3.6 improves over Firefox 3.5, IE is slow no matter what (though faster than Firefox 3.5 for vanilla <tt>jQuery.each</tt>), and the Webkit browsers are both very fast. What's more interesting is to look at each time as a percentage of the stock jQuery implementation:</p>
<table class="datatable numbers">
<caption>Percentage of time taken to iterate over 500,000 integers compared to regular <tt>jQuery.each</tt>.</caption>
<tr>
<th></th>
<th><tt>Array.forEach</tt> (same signature as jQuery)</th>
<th><tt>Array.forEach</tt> (native signature)</th>
<th>Unvarying '<tt>this</tt>'</th>
<th>No <tt>call</tt></th>
</tr>
<tr>
<th>Firefox 3.5</th>
<td>117%</td>
<td style="background-color: #D6FFD0">27%</td>
<td>42%</td>
<td>35%</td>
</tr>
<tr>
<th>Firefox 3.6rc2</th>
<td>123%</td>
<td>37%</td>
<td>36%</td>
<td style="background-color: #D6FFD0">20%</td>
</tr>
<tr>
<th>Firefox 3.7a1pre</th>
<td>122%</td>
<td>33%</td>
<td style="background-color: #D6FFD0">20%</td>
<td>57%</td>
</tr>
<tr>
<th>Chrome 3</th>
<td>116%</td>
<td>51%</td>
<td>47%</td>
<td style="background-color: #D6FFD0">43%</td>
</tr>
<tr>
<th>Safari 4</th>
<td>189%</td>
<td>188%</td>
<td>128%</td>
<td>104%</td>
</tr>
<tr>
<th>IE 8</th>
<td>96%</td>
<td>88%</td>
<td>94%</td>
<td style="background-color: #D6FFD0">60%</td>
</tr>
<tr>
<th>Opera 10.10</th>
<td>156%</td>
<td>63%</td>
<td>68%</td>
<td style="background-color: #D6FFD0">51%</td>
</tr>
</table>
<p>A couple of things jump out at us - <tt>Array.forEach</tt> doesn't buy us anything if we have to provide a callback to reverse the inputs. If we can use the native <tt>forEach</tt> signature, it gets much faster, but not by an order of magnitude. Not varying <tt>this</tt> helps a lot in Firefox and Chrome - I suspect some runtime optimizations kick in if <tt>this</tt> stays the same, but not if it's changing. The overhead of <tt>call</tt> is significant - it tends to matter more than anything else here. The last thing to note is that, weirdly, Safari 4 is fastest with the stock <tt>jQuery.each</tt> - I wonder if they've optimized specifically for that pattern.</p>
<p>Armed with this knowledge, I customized a copy of jQuery 1.4 to stop referring to <tt>this</tt> in its uses of <tt>each</tt>, switched the <tt>for</tt> loop to call the callback directly instead of using <tt>call</tt>, and reverse-engineered <a href="http://ejohn.org/files/jquery1.4/slick/?type=attr">the performance tests</a> John Resig used for the <a href="http://jquery14.com/day-01">jQuery 1.4 release notes</a>. Using these tests, I compared my custom version to the released jQuery 1.4. </p>
<p>The result: <b>optimizing array iteration speed made no difference</b>. The real work being done by jQuery (DOM manipulation, etc) totally overshadows any array iteration overhead. Reducing that overhead even by 80% doesn't matter at all. We learned a few things about how fast <tt>Array.forEach</tt> is and how setting <tt>this</tt> in <tt>call</tt> affects performance, but we haven't found some magic way to make our code, or jQuery overall, any faster. Furthermore, the only improvement that would have preserved the signature of the original jQuery API was actually slower than the existing implementation! It's not worth losing <tt>this</tt> in <tt>each</tt> for any of these speed gains.</p>
<p>There was one small improvement to jQuery, however - a very small boost to the compressability of the library. Using explicit arguments to <tt>each</tt> instead of <tt>this</tt> to refer to the current element being iterated means that YUI Compressor or Google Closure Compiler can use one character for that item, instead of 4 for <tt>this</tt> (since <tt>this</tt> is a keyword). In practice, that saved about 197 bytes out of 69,838 - still not a huge win. But I like to avoid using <tt>this</tt> in my <tt>each</tt> anyway, just so I get to use semantically meaningful variable names, so it's nice to see that I'm saving a byte or two along the way.</p>
<p>PS: Aside from the "jQueryness" of it, I wondered why <tt>each</tt> set <tt>this</tt> to the current element in the array anyway. I have one idea - if <tt>this</tt> is set to the current element in the array for each invocation of the callback, you can do cleaner OO-style JavaScript. For example, let's say you have a <tt>Dialog</tt> object that has a <tt>close</tt> method. Of course the <tt>close</tt> method would just use <tt>this</tt> to refer to the object it's a member of. But if you had an array of <tt>Dialog</tt>s and wanted to say "<tt>$.each(dialogs, Dialog.prototype.close)</tt>" and <tt>each</tt> <em>didn't</em> set <tt>this</tt> to each <tt>Dialog</tt> in turn, everything would get confused. Of course, in jQuery 1.4 you can get around this using <a href="http://api.jquery.com/jQuery.proxy/"><tt>jQuery.proxy</tt></a>, which goes ahead and uses <tt>apply</tt> (a variant of <tt>call</tt>) anyway.</p>
]]></content:encoded>
			<wfw:commentRss>http://benhollis.net/blog/2010/01/23/speeding-up-jquerys-each-function/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Investigating JavaScript Array Iteration Performance</title>
		<link>http://benhollis.net/blog/2009/12/13/investigating-javascript-array-iteration-performance/</link>
		<comments>http://benhollis.net/blog/2009/12/13/investigating-javascript-array-iteration-performance/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 02:26:45 +0000</pubDate>
		<dc:creator>Ben Hollis</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[underscore.js]]></category>

		<guid isPermaLink="false">http://brh.numbera.com/blog/?p=390</guid>
		<description><![CDATA[The other day I was working on some JavaScript code that needed to iterate over huge arrays. I was using jQuery&#8217;s $.each function just because it was simple, but I had heard from a bunch of articles on the web that $.each was much slower than a normal for loop. That certainly made sense, and [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I was working on some JavaScript code that needed to iterate over huge arrays. I was using jQuery&#8217;s <a href="http://docs.jquery.com/Utilities/jQuery.each#objectcallback"><tt>$.each</tt></a> function just because it was simple, but I had heard from a bunch of articles on the web that <tt>$.each</tt> was much slower than a normal for loop. That certainly made sense, and switching to a normal for loop sped up my code quite a bit in the sections that dealt with large arrays.</p>
<p>I&#8217;d also recently seen an article on <a href="http://ajaxian.com">Ajaxian</a> about a new library, <a href="http://documentcloud.github.com/underscore/">Underscore.js</a> that claimed to include, among other nice Ruby-style functional building blocks, an <tt>each</tt> function that was powered by the JavaScript 1.5 <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach"><tt>Array.forEach</tt></a> when it was available (and degrading for IE). I wondered how much faster that was than jQuery&#8217;s <tt>$.each</tt>, and that got me to thinking about all the different ways to iterate over an array in JavaScript, so I decided to test them out and compare them in different browsers.</p>
<p>This gets pretty long so the rest is after the jump.<br />
<span id="more-390"></span></p>
<p>I went with six different approaches for my test. Each function would take a list of 100,000 integers and add them together. <a href="/experiments/browserdemos/foreach/array-iteration.html">You can try the test yourself.</a> The first was a normal  <tt>for</tt> loop, with <a href="http://en.wikipedia.org/wiki/Loop-invariant_code_motion">the loop invariant hoisted</a>:</p>
<pre>
var total = 0;
var length = myArray.length;
for (var i = 0; i < length; i++) {
  total += myArray[i];
}
return total;
</pre>
<p>And then again without the invariant hoisted, just to see if it makes a difference:</p>
<pre>
var total = 0;
for (var i = 0; i < myArray.length; i++) {
  total += myArray[i];
}
return total;
</pre>
<p>Next I tried a <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Statements/for...in"><tt>for in</tt></a> loop, which is really <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Statements/for...in#Description">not a good idea</a> for iterating over an array at all - it's really for iterating over the properties of an object - but is included because it's interesting and some people try to use it for iteration:</p>
<pre>
var total = 0;
for (i in myArray) {
  total += myArray[i];
}
return total;
</pre>
<p>Next I tried out the  <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach"><tt>Array.forEach</tt></a> included in JavaScript 1.5, on its own. Note that IE doesn't support this (surprised?):</p>
<pre>
var total = 0;
myArray.forEach(function(n, i){
  total += n;
});
return total;
</pre>
<p>After that I tested Underscore.js 0.5.1's <a href="http://documentcloud.github.com/underscore/#each"><tt>_.each</tt></a>:</p>
<pre>
var total = 0;
_.each(myArray, function(i, n) {
  total += n;
});
return total;
</pre>
<p>And then jQuery 1.3.2's <tt>$.each</tt>, which differs from Underscore's in that it doesn't use the native  <tt>forEach</tt> where available, and <tt>this</tt> is set to each element of the array as it is iterated:</p>
<pre>
var total = 0;
$.each(myArray, function(i, n){
  total += n;
});
return total;
</pre>
<p>I tested a bunch of browsers I had lying around - Firefox 3.5, Chrome 3, Safari 4, IE 8, Opera 10.10, and Firefox 3.7a1pre (the bleeding edge build, because I wanted to know if Firefox is getting faster). I tried testing on IE6 and IE7 in VMs but they freaked out and crashed. The tests iterated over a list of 100,000 integers, and I ran each three times and averaged the results. Note that this is not a particularly rigorous test - other stuff was running on my computer, some of the browsers were run in VMs, etc. I mostly wanted to be able to compare different approaches within a single browser, not compare browsers, though some differences were readily apparent after running the tests.</p>
<table class="datatable numbers">
<caption>Time to iterate over an array of 100,000 integers</caption>
<tr>
<th></th>
<th><tt>for</tt> loop</th>
<th><tt>for</tt> loop (unhoisted)</th>
<th><tt>for in</tt></th>
<th><tt>Array.forEach</tt></th>
<th>Underscore.js <tt>each</tt></th>
<th><tt>jQuery.each</tt></th>
</tr>
<tr>
<th>Firefox 3.5</th>
<td>2ms</td>
<td>2ms</td>
<td>78ms</td>
<td>72ms</td>
<td>69ms</td>
<td style="background-color: #FFD0D0">225ms</td>
</tr>
<tr>
<th>Firefox 3.7a1pre</th>
<td>2ms</td>
<td>3ms</td>
<td>73ms</td>
<td>29ms</td>
<td>34ms</td>
<td>108ms</td>
</tr>
<tr>
<th>Chrome 3</th>
<td>2ms</td>
<td>2ms</td>
<td>35ms</td>
<td>6ms</td>
<td style="background-color: #D6FFD0">5ms</td>
<td>14ms</td>
</tr>
<tr>
<th>Safari 4</th>
<td>1ms</td>
<td>2ms</td>
<td style="background-color: #FFD0D0">162ms</td>
<td>16ms</td>
<td>15ms</td>
<td style="background-color: #D6FFD0">10ms</td>
</tr>
<tr>
<th>IE 8</th>
<td>17ms</td>
<td style="background-color: #FFD0D0">41ms</td>
<td>265ms</td>
<td>n/a</td>
<td>127ms</td>
<td>133ms</td>
</tr>
<tr>
<th>Opera 10.10</th>
<td>15ms</td>
<td>19ms</td>
<td>152ms</td>
<td>53ms</td>
<td>57ms</td>
<td>74ms</td>
</tr>
</table>
<p>I've highlighted some particularly interesting good and bad results from the table (in green and red, respectively). Let's see what we can figure out from these tests. I'll get the obvious comparisons between browsers out of the way - IE is really slow, and Chrome is really fast. Other than that, they each seem to have some mix of strengths and weaknesses.</p>
<p>First, the <tt>for</tt> loop is really fast. It's hard to beat, and it's clear that if you've got to loop over a ton of elements and speed is important to you you should be using a <tt>for</tt> loop. It's sad that it's so much slower in IE and Opera, but it's still faster than the alternative. Opera's result is somewhat surprising - while it's not particularly fast anywhere, it's not nearly as slow as IE on the other looping methods, but it's still pretty slow on normal <tt>for</tt> loops. Notice that IE8 is the only browser where manually hoisting the loop invariant in the <tt>for</tt> loop matters - by almost 3x. I'm guessing every other browser automatically caches the <tt>myArray.length</tt> result, leading to roughly the same performance either way, but IE doesn't.</p>
<p>Next, it turns out that <tt>for in</tt> loops are not just incorrect, they're slow - even in otherwise blazingly-fast Chrome. In every browser there's a better choice, and it doesn't even get you much in terms of convenience (since it iterates over indices of the array, not values). Safari is particularly bad with them - they're 10x slower than its next slowest benchmark. Just don't use <tt>for in</tt>!</p>
<p>The results for the native <tt>Array.forEach</tt> surprised me. I expected some overhead because of the closure and function invocation on the passed-in iterator function, but I didn't expect it to be so much slower. Chrome and Safari seem to be pretty well-optimized, though it is still several times slower than the normal <tt>for</tt> loop, but Firefox and Opera really chug along - especially Firefox. Firefox 3.7a1pre seems to have optimized <tt>forEach</tt> a bit (probably more than is being shown, since 3.7a1pre was running in a VM while 3.5 was running on my normal OS).</p>
<p>Underscore.js <tt>each</tt>'s performance is pretty understandable, since it boils down to native <tt>forEach</tt> in most browsers, it performs pretty much the same. However, in IE it has to fall back to a normal <tt>for</tt> loop and invoke the iterator function itself for each element, and it slows way down. What's most surprising about that is that having Underscore invoke a function for each element within a for loop is still 10x slower in IE than just using a <tt>for</tt> loop! There must be a lot of overhead in invoking a function with <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Function/call"><tt>call</tt></a> in IE - or maybe just in invoking functions in general.</p>
<p>Lastly we have jQuery's <tt>each</tt>, which (excluding for in loops) is the slowest method of iterating over an array in most of the browsers tested. The exception is Safari, which consistently does better with jQuery's each than it does with Underscore's or the native <tt>forEach</tt>. I'm really not sure why, though the difference is not huge. IE's performance here is pretty much expected, since Underscore degrades to almost the same code as jQuery's when a native <tt>forEach</tt> isn't available. Firefox 3.5 is the real shocker - it's drastically slower with jQuery's <tt>each</tt>. It's even slower than IE8, and by a wide margin! Firefox 3.7a1pre makes things better, but it's still pretty embarassing. I have some theories on why it's so slow in Firefox and what could be done about it, but those will have to wait for another post.</p>
<p>It'd be interesting to try out some of the other major JavaScript libraries' iteration functions and compare them with jQuery and Underscore's speeds - I'm admittedly a jQuery snob, but it'd be interesting to see if other libraries are faster or not.</p>
<p>It's worth noting that, as usual, this sort of performance information only matters if you're actually seeing performance problems - don't rewrite your app to use <tt>for</tt> loops or pull in Underscore.js if you're only looping over tens, or hundreds, or even thousands of items. The convenience of jQuery's functional-style <tt>each</tt> means it's going to stay my go-to for most applications. But if you're seeing performance problem iterating over large arrays, hopefully this will help you speed things up.</p>
]]></content:encoded>
			<wfw:commentRss>http://benhollis.net/blog/2009/12/13/investigating-javascript-array-iteration-performance/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Swoopo Profits Greasemonkey Script &#8211; Entertainment Shopping</title>
		<link>http://benhollis.net/blog/2009/10/11/swoopo-profits-greasemonkey-script-entertainment-shopping/</link>
		<comments>http://benhollis.net/blog/2009/10/11/swoopo-profits-greasemonkey-script-entertainment-shopping/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 20:30:38 +0000</pubDate>
		<dc:creator>Ben Hollis</dc:creator>
				<category><![CDATA[Greasemonkey]]></category>
		<category><![CDATA[evil plan]]></category>
		<category><![CDATA[penny auction]]></category>
		<category><![CDATA[swoopo]]></category>

		<guid isPermaLink="false">http://brh.numbera.com/blog/?p=381</guid>
		<description><![CDATA[In the last few weeks I&#8217;ve become increasingly obsessed with the evil genius that is Swoopo.com. Swoopo is a penny-auction site &#8211; users buy bids for $0.60, and each bid placed on an item increases the price by $0.12. The cost of bids and the amount they increase the price of the item vary depending [...]]]></description>
			<content:encoded><![CDATA[<p>In the last few weeks I&#8217;ve become increasingly obsessed with the evil genius that is <a href="http://en.wikipedia.org/wiki/Swoopo">Swoopo.com</a>. Swoopo is a <a href="http://en.wikipedia.org/wiki/Penny_auction">penny-auction site</a> &#8211; users buy bids for $0.60, and each bid placed on an item increases the price by $0.12. The cost of bids and the amount they increase the price of the item vary depending on the type of auction and the country you&#8217;re in. Swoopo does a lot to make it harder to win, though. For example, if the bid is placed within 10 seconds of the end of an auction, the closing time of the auction is extended by 10 seconds or so, so people can have last-second-sniping wars for as long as they want. They also offer a &#8220;BidButler&#8221; service that will automatically bid for you, and of course if two users in an auction are using it, the BidButlers just fight until they&#8217;ve used up all the money they were given. Swoopo&#8217;s operation is like cold fusion for money &#8211; they make insane amounts of cash off their users, and they only have to <a href="http://en.wikipedia.org/wiki/Drop_shipping">drop-ship</a> the item to one user so there&#8217;s theoretically very little operating cost (they already have the money from selling bids, and they don&#8217;t need to maintain inventory). They&#8217;re shameless enough to even have auctions for cash, <a href="http://www.swoopo.com/auction/1-ounce-gold-bar-31-10g-/227470.html">gold</a>, and even <a href="http://www.swoopo.com/auction/50-bids-voucher/226130.html">more bids</a>! Because everyone in the auction is paying to participate, even if the winner gets some savings on the item, Swoopo makes far, far more on the sunk bids &#8211; sometimes 10x the price of the item in pure profit. </p>
<p>Jeff Atwood (of <a href="http://codinghorror.com">codinghorror.com</a>)<a href="http://www.codinghorror.com/blog/archives/001196.html"> has written about Swoopo</a> <a href="http://www.codinghorror.com/blog/archives/001261.html">multiple times</a>, and some techies have even <a href="http://jcs.org/notaweblog/2009/03/06/trying_to_game_swoopo_com/">tried to game the system</a>, but it hasn&#8217;t worked. I was introduced to Swoopo through Jeff&#8217;s blog but I hadn&#8217;t thought about it forever, and for some reason it came up again recently. After looking at it a bit, I was just floored by how they&#8217;ve managed to set up such a perfect money-generating system. The company that runs Swoopo is called &#8220;Entertainment Shopping&#8221;, which I guess is supposed to be a suggestion that it&#8217;s like gambling (where it&#8217;s &#8220;fun&#8221; to lose money) though they really, really don&#8217;t want to be regulated as gambling. I don&#8217;t personally find gambling (or bidding on Swoopo) to be that fun, but I <em>do</em> find it entertaining to watch the astronomical profits tick up as more and more suckers toss money into an auction. So <a href="http://brh.numbera.com/software/greasemonkeyscripts/">I built a little Greasemonkey script</a> that&#8217;ll add the estimated profit to Swoopo above the price of an auction, updating in real time as people place bids.</p>
<p class="blogimage"><a href="http://brh.numbera.com/software/greasemonkeyscripts/"><img src="http://brh.numbera.com/software/greasemonkeyscripts/images/swoopo_screen.png" width="299" height="385" alt="Example screenshot of Swoopo Profits" /></a></p>
<p>It took quite a bit of work to sniff out the prices from the page (I suspect they make it hard to scrape on purpose), but I&#8217;ve checked it out and the script works pretty well on current and recent auctions on all of Swoopo&#8217;s different sites (US, Canada, UK, Germany, Austria, and Spain). It won&#8217;t work on some of their older auctions, where the rules were slightly different (and bid costs were different, too). The basic formula looks like this:</p>
<p class="blogimage">
<tt>((currentPrice - bidAmount) / bidAmount) * bidCost + currentPrice - worthUpTo</tt>
</p>
<p>I&#8217;m calculating it with all the fairness to Swoopo I can muster. I calculate the number of bids based on the current price and the amount each bid moves the price (bidAmount) times the cost of bids (bidCost). The winner still has to pay the current price, so I add that in, but I subtract what Swoopo says the item is &#8220;worth up to&#8221; since they probably have to pay around that to drop-ship it to a customer. As the example screenshot shows, this leads to examples like an iMac selling for $364.75 (plus another $392.40 in bids for the winner), but a total pure profit of $9,827.98 for Swoopo. Exciting! I&#8217;ll readily admit that my calculation is not always 100% accurate. There are a number of things I don&#8217;t take into account &#8211; I assume shipping is a wash, so it&#8217;s not included. I assume Swoopo&#8217;s paying the full retail &#8220;worth up to&#8221; price when they&#8217;re probably not. I count bids as all costing the same even though they might have been won at a &#8220;discount&#8221; via a bid auction. In cases where I can&#8217;t figure out some numbers I default them to hardcoded values, which might be wrong. I also don&#8217;t take into account &#8220;Swoop it now&#8221;, which lets bidders buy the item for its full price minus the money they&#8217;ve sunk into bids, effectively getting out of the auction entirely. This would reduce Swoopo&#8217;s profits but it isn&#8217;t recorded anywhere so I can&#8217;t factor it in. So take the number with a grain of salt &#8211; it&#8217;s <em>entertainment</em>.</p>
<p><a href="http://brh.numbera.com/software/greasemonkeyscripts/">Grab the script</a> and start poking around swoopo.com. Hopefully you&#8217;ll have as much fun as I have with it.</p>
<p>As a side note about my Greasemonkey scripts, I&#8217;ve retired the &#8220;Amazon Super Saver Snooper&#8221; script. Amazon has changed the way the API used to look up Super Saver eligability works, and I can&#8217;t get at that data anymore. More importantly, Amazon now puts &#8220;Prime&#8221; logos next to Prime-shippable items, so the script isn&#8217;t necessary anymore.</p>
]]></content:encoded>
			<wfw:commentRss>http://benhollis.net/blog/2009/10/11/swoopo-profits-greasemonkey-script-entertainment-shopping/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
