<?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>Jay Paroline - Grooveshark Dev</title>
	<atom:link href="http://wanderr.com/jay/feed/" rel="self" type="application/rss+xml" />
	<link>http://wanderr.com/jay</link>
	<description>Rantings of a Grooveshark Developer</description>
	<lastBuildDate>Mon, 21 Dec 2009 18:32:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Attn Hackers: Opening up Grooveshark</title>
		<link>http://wanderr.com/jay/attn-hackers-opening-up-grooveshark/2009/12/21/</link>
		<comments>http://wanderr.com/jay/attn-hackers-opening-up-grooveshark/2009/12/21/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 18:32:41 +0000</pubDate>
		<dc:creator>Jay</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://wanderr.com/jay/?p=260</guid>
		<description><![CDATA[At Grooveshark, we get a lot of requests for features that aren&#8217;t possible to create in Adobe Flash/Flex/Air or that we just plain don&#8217;t have time to do.
In that vein, we&#8217;re working on opening up Grooveshark to make it a bit more extensible.
The first thing we&#8217;re doing is making the player status really easy to [...]]]></description>
			<content:encoded><![CDATA[<p>At Grooveshark, we get a lot of requests for features that aren&#8217;t possible to create in Adobe Flash/Flex/Air or that we just plain don&#8217;t have time to do.</p>
<p>In that vein, we&#8217;re working on opening up Grooveshark to make it a bit more extensible.</p>
<p>The first thing we&#8217;re doing is making the player status really easy to get to. People want their chat clients to be able to reflect what&#8217;s playing in the status when they are listening to the desktop app. We can&#8217;t do that through AIR directly, and we&#8217;re not going to have time to learn about and write special code for each chat client out there, but now anyone who already knows about that stuff or just really wants to put the time into it can do it.<br />
There is a file that we are storing in documentsDirectory\Grooveshark\currentSong.txt<br />
documentsDirectory is defined by Adobe to be the current users&#8217; documents directory. In windows that&#8217;s %HOMEPATH%\Documents\Grooveshark\currentSong.txt</p>
<p>The format of the file is pretty obvious if you open it up, but I&#8217;ll spell it out here:<br />
SongName\tAlbumName\tArtistName\tStatus<br />
where \t is a hard tab (note: names are guaranteed not to have tabs in them)<br />
Valid statuses are &#8220;playing,&#8221; &#8220;paused&#8221; and &#8220;stopped&#8221; &#8211; we may add others later if it makes sense to do so. Note that if a user clears their queue or quits Grooveshark, the last song to play will still be listed with a status of &#8220;stopped&#8221;.</p>
<p>Other ways we plan to open up Grooveshark to 3rd party developers includes creating an external interface through javascript for the web client so people can make Firefox or Chromium extensions to control playback, and creating something similar that can allow the desktop app to accept connections from 3rd party apps running on the desktop alongside, so for example someone could write a plugin that registers global keybaord shortcuts for play/pause, back and next. Again, AIR will not allow us to register those shortcuts directly.</p>
]]></content:encoded>
			<wfw:commentRss>http://wanderr.com/jay/attn-hackers-opening-up-grooveshark/2009/12/21/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>The Case of the Crazy Driver</title>
		<link>http://wanderr.com/jay/the-case-of-the-crazy-driver/2009/12/09/</link>
		<comments>http://wanderr.com/jay/the-case-of-the-crazy-driver/2009/12/09/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 10:27:34 +0000</pubDate>
		<dc:creator>Jay</dc:creator>
				<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://wanderr.com/jay/?p=256</guid>
		<description><![CDATA[I often work nights at Grooveshark, which means I also drive home very late or very early, depending on your perspective.
A few times on my way home, I&#8217;ve noticed somebody driving in a fashion that can only be summed up as &#8216;crazy.&#8217; From a distance it looks like they start to pull up into somebody&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I often work nights at Grooveshark, which means I also drive home very late or very early, depending on your perspective.</p>
<p>A few times on my way home, I&#8217;ve noticed somebody driving in a fashion that can only be summed up as &#8216;crazy.&#8217; From a distance it looks like they start to pull up into somebody&#8217;s driveway, then turn onto the sidewalk, then back onto the road, and then back up onto the sidewalk again, until I or some other car gets near, then they zoom off down some side street.</p>
<p>Tonight I saw that again and I was on my scooter, so I decided to follow the car down the side street. It didn&#8217;t take them long to realize they were being followed, so they started driving even more crazily, speeding and running stop signs, turning off on even more side streets, but still sometimes pulling up onto the sidewalk and then veering off. I started to get freaked out at how freaked out this person was, and how crazy they were driving, afraid that they would decide to try to run me over or something, so I gave up. I turned around and took off, but not before looking back. And at that moment the car I had been following was pulled onto the sidewalk again, and I finally saw the detail I had been missing before. What I saw was a newspaper flying out the window of the car. My crazy driver was just a person delivering papers.</p>
]]></content:encoded>
			<wfw:commentRss>http://wanderr.com/jay/the-case-of-the-crazy-driver/2009/12/09/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bugzilla error</title>
		<link>http://wanderr.com/jay/bugzilla-error/2009/09/23/</link>
		<comments>http://wanderr.com/jay/bugzilla-error/2009/09/23/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 10:16:22 +0000</pubDate>
		<dc:creator>Jay</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://wanderr.com/jay/?p=254</guid>
		<description><![CDATA[Setting up Bugzilla for a friend on a slicehost account running RHEL5, I ran into issues following the official installation guide.
After running:
./checksetup.pl --check-modules
/usr/bin/perl install-module.pl --all

The error message I received was: 
Can&#8217;t exec &#8220;&#8211;decompress&#8221;: No such file or directory
Amazingly, I found no exact matches for this in Google (my google-fu is generally weak, however). It turns [...]]]></description>
			<content:encoded><![CDATA[<p>Setting up Bugzilla for a friend on a slicehost account running RHEL5, I ran into issues following the official <a href="http://www.bugzilla.org/docs/3.4/en/html/installation.html">installation guide</a>.<br />
After running:<br />
<code>./checksetup.pl --check-modules<br />
/usr/bin/perl install-module.pl --all<br />
</code><br />
The error message I received was: </p>
<blockquote><p>Can&#8217;t exec &#8220;&#8211;decompress&#8221;: No such file or directory</p></blockquote>
<p>Amazingly, I found no exact matches for this in Google (my google-fu is generally weak, however). It turns out that in order for the module installer to be able to install the modules it needs, there&#8217;s a certain module it needs! </p>
<p><code>yum install perl-Compress-Zlib.x86_64<br />
yum install perl-Archive-Tar.noarch</code><br />
makes everything happy again.</p>
<p>Nothing earth shattering, but maybe now Google will have an answer if anyone else runs into this.</p>
]]></content:encoded>
			<wfw:commentRss>http://wanderr.com/jay/bugzilla-error/2009/09/23/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Order of Operations Gotcha</title>
		<link>http://wanderr.com/jay/php_order_of_operation/2009/09/04/</link>
		<comments>http://wanderr.com/jay/php_order_of_operation/2009/09/04/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 15:59:35 +0000</pubDate>
		<dc:creator>Jay</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://wanderr.com/jay/?p=252</guid>
		<description><![CDATA[PHP&#8217;s decision to give addition, subtraction and string concatenation equal precedence has caused some difficult to track down bugs on several occasions. It&#8217;s so non-intuitive I have difficulty remembering this one, and hence keep writing wrong code.
Example:
$tacos = "Robots: " . 1 + 2 . " for the win!";
I think a normal human would expect [...]]]></description>
			<content:encoded><![CDATA[<p>PHP&#8217;s decision to give addition, subtraction and string concatenation equal precedence has caused some difficult to track down bugs on several occasions. It&#8217;s so non-intuitive I have difficulty remembering this one, and hence keep writing wrong code.</p>
<p>Example:</p>
<p><code>$tacos = "Robots: " . 1 + 2 . " for the win!";</code></p>
<p>I think a normal human would expect $tacos to be equal to &#8220;Robots: 3 for the win!&#8221;. But the result is actually &#8220;2 for the win!&#8221;</p>
<p>What gives? Well, the PHP docs say that plus, minus and string concatenation all get equal precedence, with left associativity. So going from left to right, it says:<br />
&#8220;Robots: &#8221; . 1 | &#8220;Robots: 1&#8243; so far, so good.<br />
&#8220;Robots: 1&#8243; + 2 => (int)&#8221;Robots: 1&#8243; + 2; | &#8220;Robots: 1&#8243; converts to 0, so 0 + 2<br />
2 . &#8221; for the win!&#8221; | &#8220;2 for the win!&#8221; D&#8217;oh!</p>
<p>I think it would make a lot more sense for string concatenation to take a lower precedence than any arithmetic. </p>
<p>The correct way to write the above code is:</p>
<p><code>$tacos = "Robots: " . (1 + 2) . " for the win!";</code></p>
]]></content:encoded>
			<wfw:commentRss>http://wanderr.com/jay/php_order_of_operation/2009/09/04/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Free eBook for VIP users</title>
		<link>http://wanderr.com/jay/free-ebook-for-vip-users/2009/09/01/</link>
		<comments>http://wanderr.com/jay/free-ebook-for-vip-users/2009/09/01/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 19:24:42 +0000</pubDate>
		<dc:creator>Jay</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://wanderr.com/jay/?p=250</guid>
		<description><![CDATA[&#8230;sorta.
It looks like there was a mix up and a bunch of our VIP users received the following email:
Andrew Wise
 to me
show details 2:10 PM (3 minutes ago)
Hi,
Thanks for purchasing our eBook, please download the eBook from this email.
http://tripletsmommy.com/wp-content/themes/typebased/ebook1.zip
Having not actually purchased an eBook, some of our users thought this was a weird form of [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230;sorta.</p>
<p>It looks like there was a mix up and a bunch of our VIP users received the following email:</p>
<blockquote><p>Andrew Wise<br />
 to me</p>
<p>show details 2:10 PM (3 minutes ago)</p>
<p>Hi,</p>
<p>Thanks for purchasing our eBook, please download the eBook from this email.</p>
<p>http://tripletsmommy.com/wp-content/themes/typebased/ebook1.zip</p></blockquote>
<p>Having not actually purchased an eBook, some of our users thought this was a weird form of spam or phishing, or even that their accounts might have been compromised. It&#8217;s nothing as sinister as all that, however, just a flub. </p>
<p>Here&#8217;s the official explanation from BWC, sent to one of our users who originally pointed out the issue:</p>
<blockquote><p>
Hey [redacted],</p>
<p>Thanks for letting me know, and sorry for the confusion!</p>
<p>Looks like our business guy (Andrew) who handles all our PayPal and such had a little mixup between Grooveshark and one of his side-projects. I just yelled at him, and everything is sorted out now. </p>
<p>[...]</p>
<p>Let me know if there&#8217;s anything else I can do to help out. Oh, and I guess enjoy being a triplets mommy! ;)</p>
<p>Regards,</p>
<p>Ben Westermann-Clark</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://wanderr.com/jay/free-ebook-for-vip-users/2009/09/01/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Pizza Hack</title>
		<link>http://wanderr.com/jay/pizza-hack/2009/08/23/</link>
		<comments>http://wanderr.com/jay/pizza-hack/2009/08/23/#comments</comments>
		<pubDate>Sun, 23 Aug 2009 06:38:24 +0000</pubDate>
		<dc:creator>Jay</dc:creator>
				<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://wanderr.com/jay/?p=246</guid>
		<description><![CDATA[
Although I know I shouldn&#8217;t, I love Stouffer&#8217;s french bread pizza.
What I don&#8217;t love is the 30 minute cooking time in the oven, or how it comes out all soggy and gross after the recommended 5 minutes in the microwave.
The solution? 1 minute in the microwave, 10 in the toaster oven. The result? Crunchy pizza [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.stouffers.com/Products/ProductImage.ashx?ProductId=211&#038;ImageType=Package_Shot" style="float: none"/></p>
<p>Although I know I shouldn&#8217;t, I love Stouffer&#8217;s french bread pizza.<br />
What I don&#8217;t love is the 30 minute cooking time in the oven, or how it comes out all soggy and gross after the recommended 5 minutes in the microwave.</p>
<p>The solution? 1 minute in the microwave, 10 in the toaster oven. The result? Crunchy pizza perfection, in just about 1/3rd of he time.</p>
]]></content:encoded>
			<wfw:commentRss>http://wanderr.com/jay/pizza-hack/2009/08/23/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Manage Your Library</title>
		<link>http://wanderr.com/jay/manage-your-library/2009/08/21/</link>
		<comments>http://wanderr.com/jay/manage-your-library/2009/08/21/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 10:00:33 +0000</pubDate>
		<dc:creator>Jay</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://wanderr.com/jay/?p=242</guid>
		<description><![CDATA[Coming to Grooveshark 2.0 is the ability for users to add music to their library without uploading, and without even scanning in their library.
That&#8217;s right, if you find a song on Grooveshark that you like, you can add it to your library with the simple click of a button. If you have a song in [...]]]></description>
			<content:encoded><![CDATA[<p>Coming to Grooveshark 2.0 is the ability for users to add music to their library without uploading, and without even scanning in their library.</p>
<p>That&#8217;s right, if you find a song on Grooveshark that you like, you can add it to your library with the simple click of a button. If you have a song in your library that you wish would just go away, you can also remove it from your library with the simple click of a button.</p>
<p>Screenshots:<br />
<img src="http://wanderr.com/pics/lite2/addtolibrary.png" style="float: none"/><br />
You can click this button on any song row to add it to your library (note: icon subject to change)</p>
<p><img src="http://wanderr.com/pics/lite2/dragtolibrary.png" style="float: none"/><br />
You can also drag as many songs to your library at once as you&#8217;d like.</p>
<p><img src="http://wanderr.com/pics/lite2/removefromlibrary.png" style="float: none"/><br />
If you toggle this button (icon subject to change) when it is highlighted, the song will be removed from your library.</p>
<p>Reminder: We will be releasing a preview (in other words, still buggy) version of Grooveshark 2.0 to <a href="http://vip.grooveshark.com/">VIP subscribers</a> on the 24th, this upcoming Monday. Subsequent changes to Grooveshark 2.0 will depend on feedback we get from the VIP community, so we can&#8217;t predict when 2.0 will be available to the general public.</p>
]]></content:encoded>
			<wfw:commentRss>http://wanderr.com/jay/manage-your-library/2009/08/21/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New RPC Server</title>
		<link>http://wanderr.com/jay/new-rpc-server/2009/08/20/</link>
		<comments>http://wanderr.com/jay/new-rpc-server/2009/08/20/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 10:00:45 +0000</pubDate>
		<dc:creator>Jay</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://wanderr.com/jay/?p=233</guid>
		<description><![CDATA[Among the many backend enhancements coming together for Grooveshark 2.0 is a brand new RPC Server that I wrote. The format it follows is the same as the last incarnation, JSON, but it&#8217;s considerably more efficient.
First, a history lesson. Our first stab at RPC (codename tambourine) was SOAP. We chose SOAP because it did what [...]]]></description>
			<content:encoded><![CDATA[<p>Among the many backend enhancements coming together for Grooveshark 2.0 is a brand new RPC Server that I wrote. The format it follows is the same as the last incarnation, JSON, but it&#8217;s considerably more efficient.</p>
<p>First, a history lesson. Our first stab at RPC (codename tambourine) was SOAP. We chose SOAP because it did what we needed (theoretically), it was XML (so super easy for Flash to use), and it&#8217;s also super enterprisey, which appeals to certain people here, myself not included. We used NuSOAP because it supports WSDL generation, which is so annoying we did not ever, ever want to have to do that by hand. Using SOAP turned out to be a huge mistake (anyone familiar with SOAP probably could have told us that). Because it&#8217;s XML, it was super easy to break the service by returning data with, say, an unsupported character in it, or by having PHP accidentally output a newline character (say, by following the PEAR standard and having an extra newline at the end of every PHP file). Further, because browsers eat most error codes and don&#8217;t pass the codes or the accompanying data on to plugins, we had to hack NuSOAP to violate SOAP standards and return a 200 OK when generating SOAP Faults. On top of all that, and most importantly, it turns out that generating all of that XML is very expensive. So expensive that I could not test code locally on my machine before putting it on a server. So expensive that we actually got a huge performance boost by caching the generated XML in memcache.</p>
<p>After the SOAP fiasco, we wanted to try using JSON, because it&#8217;s much more terse and far less expensive to generate than XML, while still being human readable, which we value for debugging purposes. We looked at official JSON-RPC stuff, but we were spoiled by SOAP in one regard: support for headers. We got used to using headers to pass around status information that didn&#8217;t exactly belong to the method calls, and we didn&#8217;t want to give that up so I wrote my own JSON-RPC server (codenamed cowbell) modeled largely after how SOAP worked, but more efficient. My custom JSON server class was only 275 lines long to NuSOAP&#8217;s 7,994 lines for just the core file. We gave up the elaborate data type declarations (we just verbally communicated what type everything would be), but beyond that method registration worked the same way as SOAP and every other RPC implementation I&#8217;ve seen: you need a service file which registers all available methods with the RPC server, and then invokes the RPC class, passing through the raw POST data. Although I did not save benchmark information, the speed difference between my custom RPC class and NuSOAP was astronomical, so we left the RPC optimizations at that.</p>
<p>I recently came back and did some profiling out of curiosity to see how much overhead our current RPC implementation was creating, and it turned out to be about 15% plus about an extra 1.5MB of memory used. I thought about how things were working with the current implementation and realized that it&#8217;s a bit silly to be registering hundreds of methods every time the client makes a request, when you really only need information about whatever method is currently being requested. All the other information is superfluous. So in our new JSON-RPC implementation (codename more because it&#8217;s still cowbell in a way), 162 lines long, there is no &#8216;registration&#8217; of methods. Instead, the service class that would normally do the registration simply has a collection of &#8220;meta methods&#8221; which return information about the methods that make up the service when called. So the RPC server parses the request, does a little bit of reflection magic to determine which meta method to call, and calls that method to get all the information it needs in order to handle the request. What&#8217;s the overhead of this approach? Well, it hardly even registers in the profiling I&#8217;ve done. :)</p>
<p>In summary, Grooveshark 2.0 method calls should be nearly 15% faster on average than Grooveshark 1.0 calls. :)</p>
<p>P.S. On the topic of cowbell, there&#8217;s an old easter egg that we added and never got around to telling anyone about. Before Grooveshark 2.0 is lost and it&#8217;s forgotten forever, you can get to it by typing about:cowbell into the search bar.</p>
]]></content:encoded>
			<wfw:commentRss>http://wanderr.com/jay/new-rpc-server/2009/08/20/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>All /sorts/ of Improvements</title>
		<link>http://wanderr.com/jay/all-sorts-of-improvements/2009/08/19/</link>
		<comments>http://wanderr.com/jay/all-sorts-of-improvements/2009/08/19/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 11:00:46 +0000</pubDate>
		<dc:creator>Jay</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://wanderr.com/jay/?p=228</guid>
		<description><![CDATA[I mentioned in Bypassing Magic that Grooveshark 2.0 will be loading much larger data sets, and one consequence of this is that the application can do more with that data.
As you might have guessed from the punny title of this post, one of those cool things is sorting! When looking at a list of songs, [...]]]></description>
			<content:encoded><![CDATA[<p>I mentioned in <a href="http://wanderr.com/jay/bypassing-magic/2009/08/18/">Bypassing Magic</a> that Grooveshark 2.0 will be loading much larger data sets, and one consequence of this is that the application can do more with that data.</p>
<p>As you might have guessed from the punny title of this post, one of those cool things is sorting! When looking at a list of songs, artists, albums, etc., in Grooveshark 2.0, you will be able to sort that data however you like.</p>
<p>Yes, this is another excuse for me to leak a screenshot. ;)</p>
<p><img src="http://wanderr.com/pics/lite2/sort.png" alt="Grooveshark 2.0 Sorting" style="float: none" /></p>
<p>Another feature it enables which won&#8217;t make it into the VIP release of the 24th, but will be available to VIP users shortly thereafter, is live search. You&#8217;ll be able to narrow down any list of songs you&#8217;re looking at by searching within the result set.</p>
]]></content:encoded>
			<wfw:commentRss>http://wanderr.com/jay/all-sorts-of-improvements/2009/08/19/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bypassing Magic</title>
		<link>http://wanderr.com/jay/bypassing-magic/2009/08/18/</link>
		<comments>http://wanderr.com/jay/bypassing-magic/2009/08/18/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 12:00:46 +0000</pubDate>
		<dc:creator>Jay</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[grooveshark]]></category>

		<guid isPermaLink="false">http://wanderr.com/jay/?p=217</guid>
		<description><![CDATA[In my post about how we are adding client-side caching to Grooveshark 2.0, I mentioned one of the ways we are taking advantage of the fact that thanks to using Flash, we have a full-blown stateful application.
As Grooveshark evolves and the application becomes more sophisticated, the PHP layer is more and more becoming just an [...]]]></description>
			<content:encoded><![CDATA[<p>In my post about how we are adding <a href="http://wanderr.com/jay/client-side-caching/2009/08/15/">client-side caching</a> to Grooveshark 2.0, I mentioned one of the ways we are taking advantage of the fact that thanks to using Flash, we have a full-blown stateful application.</p>
<p>As Grooveshark evolves and the application becomes more sophisticated, the PHP layer is more and more becoming just an interface to the DB. The application just needs the data; it knows exactly what to do with it from there. It also only needs to ask for one type of data at a time, whereas a traditional webpage would need to load dozens of different pieces of information at the same time. So for our type of application, magic methods and ORM can really just get in the way when all we really need is to run a query, fill up an array with the results of that query, and return it.</p>
<p>Our old libraries employing ORM, magic methods and collections, were designed to meet the needs of a typical website and don&#8217;t necessarily make sense for a full-fledged application. On a webpage, you might only show 20 results at a time, so the overhead of having a bunch of getters and setters automatically fire whenever you load up your data is probably not noticeable. But in an application, you often load far more results than can be displayed, and allow the user to interact with them more richly. When you&#8217;re loading 500, or 5000 results as opposed to 20, the overhead of ORM and magic can start to really bog you down. I first noticed the overhead issue when testing new method calls for lite2, when in some cases fetching the data would take over 30 seconds, triggering my locally defined maximum execution time, <b>even when the data was already cached</b>.</p>
<p>Like any responsible developer considering making changes to code for performance reasons, I profiled our collections code using XDebug and KCachegrind, and then I rewrote the code to bypass collections, magic and all that stuff, loading data from the DB (or memcache) into an array and returning it. The difference? In the worst case, bypassing magic was an order of magnitude less work, often times far better than that. My > 30 second example took less than 1 second in the new code.</p>
<p>For Grooveshark 2.0 code, wherever makes sense, we are bypassing magic, ORM and collections and loading data directly. This of course means that Grooveshark is faster, but it also means that we can load more data at once. In most cases we can now afford to load up entire lists of songs without having to paginate the results, which in turn means fewer calls to the backend *and* much less work for the database. Whenever you must LIMIT results, you must also ORDER BY the results so they come back in an order that makes sense. Not having to ORDER results means in many cases we save an expensive filesort which often requires a temporary table in MySQL. Returning the full data set also allows the client to do more with the data, like decide how the results should actually be sorted and displayed to the user. But that&#8217;s another post&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://wanderr.com/jay/bypassing-magic/2009/08/18/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
