<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DkEMSHYzfip7ImA9WhRUFUw.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821</id><updated>2012-01-25T12:04:49.886-06:00</updated><category term="indexes" /><category term="ruby" /><category term="ignite" /><category term="postgres" /><category term="contract" /><category term="javascript" /><category term="workflow" /><category term="web" /><category term="page speed" /><category term="freshbooks" /><category term="souders" /><category term="rails_xss" /><category term="rails heroku prototype" /><category term="analytics" /><category term="conference" /><category term="photos" /><category term="rvm gemset rubymine i18n" /><category term="presentation" /><category term="software development" /><category term="git" /><category term="good_to_know" /><category term="consulting" /><category term="rails" /><category term="chicago" /><category term="script" /><category term="tuning" /><category term="video" /><category term="rmagick" /><category term="performance" /><category term="vim" /><category term="speed tracer" /><category term="lsrc" /><category term="clients" /><category term="port" /><category term="freelance" /><category term="database" /><category term="musicjam" /><category term="notes" /><category term="speed" /><category term="windycityrails" /><category term="dynatrace" /><category term="vi" /><category term="mysql" /><category term="chicagoruby" /><category term="lightning" /><category term="internet explorer" /><category term="explain" /><category term="security" /><category term="eventmachine" /><category term="remote" /><category term="wayback" /><category term="monitoring" /><category term="newrelic" /><category term="yslow" /><category term="jquery" /><category term="interview" /><category term="captcha" /><category term="ImageMagick" /><category term="invoice" /><category term="Agile" /><category term="mac" /><category term="railsconf" /><category term="statistics" /><category term="heroku" /><category term="testing" /><category term="project" /><category term="velocity" /><category term="wideteams" /><category term="vc" /><category term="gd2" /><title>Ruby on Rails Performance Tuning</title><subtitle type="html">Making Rails applications faster</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.railsperformance.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.railsperformance.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/RailsPerformance" /><feedburner:info uri="railsperformance" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;A0ABQno_eCp7ImA9WhRSEU4.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-8266970250849577306</id><published>2011-11-12T17:12:00.001-06:00</published><updated>2011-11-12T17:15:53.440-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-12T17:15:53.440-06:00</app:edited><title>Cloud tools for rapid development, prototyping and profit!</title><content type="html">Slides from my "Cloud tools for rapid development, prototyping and profit!" given in Eau Claire, Wisconsin at &lt;a href="http://www.chippewavalleycodecamp.com/"&gt;www.chippewavalleycodecamp.com&lt;/a&gt;

&lt;div style="width:425px" id="__ss_10135514"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/johnny_zebra/cloud-tools-10135514" title="Cloud tools"&gt;Cloud tools&lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse10135514" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=cloudtools-111112163816-phpapp01&amp;stripped_title=cloud-tools-10135514&amp;userName=johnny_zebra" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse10135514" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=cloudtools-111112163816-phpapp01&amp;stripped_title=cloud-tools-10135514&amp;userName=johnny_zebra" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="padding:5px 0 12px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/johnny_zebra"&gt;John McCaffrey&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-8266970250849577306?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SzFsHzlCuz3zEgS96LqXlBHv_bI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SzFsHzlCuz3zEgS96LqXlBHv_bI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SzFsHzlCuz3zEgS96LqXlBHv_bI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SzFsHzlCuz3zEgS96LqXlBHv_bI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=S84eurM2kgI:DIXM_WYJJJE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=S84eurM2kgI:DIXM_WYJJJE:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=S84eurM2kgI:DIXM_WYJJJE:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=S84eurM2kgI:DIXM_WYJJJE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=S84eurM2kgI:DIXM_WYJJJE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/S84eurM2kgI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/8266970250849577306/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/11/cloud-tools-for-rapid-development.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/8266970250849577306?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/8266970250849577306?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/S84eurM2kgI/cloud-tools-for-rapid-development.html" title="Cloud tools for rapid development, prototyping and profit!" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2011/11/cloud-tools-for-rapid-development.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUDQn47fyp7ImA9WhRTEks.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-4312985238756118134</id><published>2011-11-02T13:57:00.000-05:00</published><updated>2011-11-02T13:57:53.007-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-02T13:57:53.007-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="video" /><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="tuning" /><category scheme="http://www.blogger.com/atom/ns#" term="indexes" /><category scheme="http://www.blogger.com/atom/ns#" term="windycityrails" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="page speed" /><category scheme="http://www.blogger.com/atom/ns#" term="yslow" /><category scheme="http://www.blogger.com/atom/ns#" term="chicagoruby" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><category scheme="http://www.blogger.com/atom/ns#" term="presentation" /><title>Performance Tuning Tutorial Video 2011</title><content type="html">Rails Performance tuning presentation from WindyCityRails 2011

I had a great time giving this presentation and had lots of conversations with the audience members afterward. I even heard back from a few people that they've used the tips I covered to drastically improve the speed of their apps!

I have more to cover on this topic, and I've been working it into a workshop format so we can spend more time on each area and do some hands on. Let me know what areas are interesting to you, and maybe I'll run a beta version past you.

&lt;iframe src="http://player.vimeo.com/video/31204422?title=0&amp;amp;byline=0&amp;amp;portrait=0&amp;amp;color=eb1031" width="780" height="585" frameborder="0" webkitAllowFullScreen allowFullScreen&gt;&lt;/iframe&gt;&lt;p&gt;Most developers know how to improve initial page load performance. We know how to follow recommendations from tools like yslow and page speed. Still, we struggle with slow performance after pages are loaded.&lt;br /&gt;
&lt;br /&gt;
This talk will review:&lt;br /&gt;
&lt;br /&gt;
* The basic rules from yslow/page speed (and when to break them)&lt;br /&gt;
* Tools for finding bottlenecks and slow javascript&lt;br /&gt;
* Common javascript performance patterns and how to fix them&lt;br /&gt;
* Architectural and design approaches to improve performance&lt;br /&gt;
* Considerations for Mobile performance&lt;br /&gt;
* Performance features in HTML5 and Rails 3&lt;br /&gt;
&lt;br /&gt;
John McCaffrey has been developing applications since 1998, and is passionate about improving application performance and software development performance. John is an independent consultant focusing on bringing Rails applications to market quickly.&lt;br /&gt;
&lt;br /&gt;
Building a team? Looking to join a team? Visit the ChicagoRuby Job Board: http://jobs.chicagoruby.org.&lt;/p&gt;


Here are my slides, please let me know if you have any questions, I will answer them if I can. (there's always something that I wish I could have covered more)

&lt;br /&gt;
&lt;div id="__ss_9300600" style="width: 425px;"&gt;
&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/johnny_zebra/windycityrails-page-performance" title="Windycityrails page performance"&gt;Windycityrails page performance&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse9300600" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=windycityrailspageperformance-110917163453-phpapp01&amp;stripped_title=windycityrails-page-performance&amp;userName=johnny_zebra" /&gt;

&lt;param name="allowFullScreen" value="true"/&gt;

&lt;param name="allowScriptAccess" value="always"/&gt;

&lt;embed name="__sse9300600" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=windycityrailspageperformance-110917163453-phpapp01&amp;stripped_title=windycityrails-page-performance&amp;userName=johnny_zebra" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;div style="padding: 5px 0 12px;"&gt;
View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/johnny_zebra"&gt;John McCaffrey&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-4312985238756118134?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/pdIfruThR0CeAZ6RBI171NeMrN8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pdIfruThR0CeAZ6RBI171NeMrN8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/pdIfruThR0CeAZ6RBI171NeMrN8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pdIfruThR0CeAZ6RBI171NeMrN8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=vNNvjruivMg:vkI2iBU8G0Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=vNNvjruivMg:vkI2iBU8G0Y:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=vNNvjruivMg:vkI2iBU8G0Y:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=vNNvjruivMg:vkI2iBU8G0Y:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=vNNvjruivMg:vkI2iBU8G0Y:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/vNNvjruivMg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/4312985238756118134/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/11/performance-tuning-tutorial-video-2011.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/4312985238756118134?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/4312985238756118134?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/vNNvjruivMg/performance-tuning-tutorial-video-2011.html" title="Performance Tuning Tutorial Video 2011" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2011/11/performance-tuning-tutorial-video-2011.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkICRXkzeip7ImA9WhdaFkg.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-7088320899475014583</id><published>2011-10-26T13:42:00.001-05:00</published><updated>2011-10-26T13:42:44.782-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-26T13:42:44.782-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="statistics" /><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="speed" /><category scheme="http://www.blogger.com/atom/ns#" term="analytics" /><category scheme="http://www.blogger.com/atom/ns#" term="web" /><title>Recent Web Performance statistics</title><content type="html">&lt;div style="text-align: left;"&gt;
&lt;span style="background-color: transparent; font-size: large;"&gt;Web application Performance impact&lt;/span&gt;&lt;/div&gt;
&lt;div class="" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="" style="clear: both; text-align: left;"&gt;
Most statistics on web application performance are described in terms of public applications, but the data is still applicable to internal applications. Given some recent &lt;a href="http://www.technologyreview.com/files/54902/GoogleSpeed_charts.pdf"&gt;statistics&lt;/a&gt;, lets think about what this means for an internal application.&lt;/div&gt;
&lt;div class="" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="" style="clear: both; text-align: left;"&gt;
&lt;a href="http://3.bp.blogspot.com/-vMp8NYipmPg/TqhI2vHJ24I/AAAAAAAAOkQ/U0cgd3CdgTg/s1600/akamai_time_2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="416" id=":current_picnik_image" src="http://2.bp.blogspot.com/-8C9goLjDkt4/TqhRU_LMlMI/AAAAAAAAOlM/8-KjhkNR5x0/s640/17011014787_b35Zd.jpg" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;While content is increasing, and sites are doing more, users still expect them to be faster.&lt;span style="background-color: transparent;"&gt;&amp;nbsp;For internal apps, you can think of these graphs as showing when "a user will be annoyed and wish they could leave", "a user's flow is interrupted and they start thinking of something else", or "when they abandon the task".&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://2.bp.blogspot.com/-LBuZFFXjTSE/TqhI163bfmI/AAAAAAAAOkA/uwxiV50HHKY/s1600/1_sec_delay_lowers_conversion.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" id=":current_picnik_image" src="http://2.bp.blogspot.com/-HV4-u9yeZ-w/TqhO4bhCTQI/AAAAAAAAOkc/-00trm-NBgg/s1600/17010873686_dPwXZ.jpg" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For retail apps, it easy to think of the impact of performance on 'conversions' in terms of users making fewer purchases, but for internal applications the metrics are different. The general idea though is that if the app is slower, internal users are able to do less work, or if the app is about 'informing their decisions', then we can assume that a slow app probably leaves them less informed.&lt;br /&gt;
&lt;span style="background-color: transparent;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent;"&gt;Improving performance might allow you to:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="background-color: transparent;"&gt;Handle more customer service calls&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="background-color: transparent;"&gt;Require less staff&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="background-color: transparent;"&gt;Require less hardware&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Keep users engaged and productive&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://1.bp.blogspot.com/-UU-TYmS_LUQ/TqhI2IsCnqI/AAAAAAAAOkI/Al4PJme0YGA/s1600/perf_abandon.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-UU-TYmS_LUQ/TqhI2IsCnqI/AAAAAAAAOkI/Al4PJme0YGA/s320/perf_abandon.png" width="276" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="text-align: left;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="text-align: left;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="text-align: left;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="text-align: left;"&gt;If internal users want to leave the site, but can't, maybe they'll just go out for coffee instead, or get a new job!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-7088320899475014583?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zSrh4ty8HsDF048wYOf6ynJ7q8U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zSrh4ty8HsDF048wYOf6ynJ7q8U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zSrh4ty8HsDF048wYOf6ynJ7q8U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zSrh4ty8HsDF048wYOf6ynJ7q8U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=ecdV4rKwBas:3h8WbJ7XfIE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=ecdV4rKwBas:3h8WbJ7XfIE:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=ecdV4rKwBas:3h8WbJ7XfIE:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=ecdV4rKwBas:3h8WbJ7XfIE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=ecdV4rKwBas:3h8WbJ7XfIE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/ecdV4rKwBas" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/7088320899475014583/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/10/recent-web-performance-statistics.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/7088320899475014583?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/7088320899475014583?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/ecdV4rKwBas/recent-web-performance-statistics.html" title="Recent Web Performance statistics" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-8C9goLjDkt4/TqhRU_LMlMI/AAAAAAAAOlM/8-KjhkNR5x0/s72-c/17011014787_b35Zd.jpg" height="72" width="72" /><thr:total>0</thr:total><georss:featurename>3118 E Lincoln Hwy, Lynwood, IL 60411, USA</georss:featurename><georss:point>41.508577297439324 -87.5390625</georss:point><georss:box>38.46560379743932 -92.59277349999999 44.551550797439326 -82.48535150000001</georss:box><feedburner:origLink>http://www.railsperformance.com/2011/10/recent-web-performance-statistics.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUENQns_eyp7ImA9WhdbGUs.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-2069004838231477014</id><published>2011-10-18T14:54:00.003-05:00</published><updated>2011-10-18T14:54:53.543-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-18T14:54:53.543-05:00</app:edited><title>RailsPerformance.com</title><content type="html">I was finally able to acquire the domain 'RailsPerformance.com', which had formerly pointed to &lt;a href="http://yehudakatz.com/"&gt;http://yehudakatz.com/&lt;/a&gt;.&amp;nbsp;&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Along with the new domain, I am focusing my efforts exclusively on Ruby on Rails application development and performance tuning. This site will continue to be a solid resource for &lt;a href="http://www.railsperformance.com/search/label/performance"&gt;Performance&lt;/a&gt; related content, as well as a way to contact me for Development services, Application Review, or a Performance analysis.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
If you'd like to get in touch, please email me at Railsperformance@gmail.com&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-2069004838231477014?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hFfQFniZrqez2ddqR_J3s28NiTU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hFfQFniZrqez2ddqR_J3s28NiTU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hFfQFniZrqez2ddqR_J3s28NiTU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hFfQFniZrqez2ddqR_J3s28NiTU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=PGzfsqvmA0w:aREphdoQKAw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=PGzfsqvmA0w:aREphdoQKAw:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=PGzfsqvmA0w:aREphdoQKAw:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=PGzfsqvmA0w:aREphdoQKAw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=PGzfsqvmA0w:aREphdoQKAw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/PGzfsqvmA0w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/2069004838231477014/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/10/railsperformancecom.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/2069004838231477014?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/2069004838231477014?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/PGzfsqvmA0w/railsperformancecom.html" title="RailsPerformance.com" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.railsperformance.com/2011/10/railsperformancecom.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UNRHY5fSp7ImA9WhdbE0k.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-8288484396376245838</id><published>2011-10-11T11:08:00.000-05:00</published><updated>2011-10-11T11:08:15.825-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-11T11:08:15.825-05:00</app:edited><title>Improving application Performance by tracking user Workflow</title><content type="html">&lt;span style="font-size: large;"&gt;Where do I begin?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
While it's a common mantra that you don't want to prematurely optimize your application, that doesn't mean that you shouldn't measure where things are at or take the time to know what your current numbers are.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-size: large;"&gt;If you aren't measuring, how do you know if you've improved anything?&lt;/span&gt;&lt;/blockquote&gt;
&lt;span style="font-size: large;"&gt;Monitor your server Log files&lt;/span&gt;&lt;br /&gt;
A good place to start is to regularly review your log files and get familiar with the average request times. Track the most frequent requests, the slowest requests, and errors, as a baseline for comparison. As you roll out new features and add more users, keep an eye changes to your base numbers. When used in conjunction with page analytics tools like Google Analytics, you can track the relationship between the performance of pages, and your site's goals. You also want to get a sense of what a typical 'session' looks like for your users. How long are they on? What actions do they take? Is there a peak time of day or day of the week that gets the most action? You aren't just looking for the slowest requests, but for all the requests it took for the user to get what they needed.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Track your overall page load time&lt;/span&gt;&lt;br /&gt;
In addition to server performance and page analytics, its important to have a sense of how long a page takes to load, including images, stylesheets, and javascript. While the server might only take 200ms to return your 'Sign up now!' page, the user might have to wait a full 12sec before all the images and content is fully loaded...and most people won't wait that long! &amp;nbsp;Taking a moment to sketch out the page flow of a new user can help you understand which pages to optimize, and which files can be cached to improve the feel of the app, and the same can be done for returning users.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Ask users about the speed&lt;/span&gt;&lt;br /&gt;
Most of the time your users will tell you when things are extremely slow, but by then they are already frustrated. Its worth the effort to establish a good relationship with a few 'user advocates' that represent the main user types you have, in order to survey them on new features, ask them about any issues, and basically keep tabs on the pulse of your app. While errors in functionality tend to prevent users from completing a transaction, performance issues prevent them from completing MORE transactions. Ask your users what parts of the application could benefit from being faster, and what that would mean to the user. "If I could see the results and narrow/filter by these core criteria, and see user ratings without leaving the search results page, I could buy more clothes for my daughter on my lunch break"&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Optimize the user's workflow&lt;/span&gt;&lt;br /&gt;
Some performance improvements come straight from a development change, like querying the database more efficiently, loading less data, or caching common results, but there are often significant improvements to be made by optimizing the way the users use the application, by improving the design.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;For example:&lt;/b&gt;&lt;br /&gt;
A common pattern I've seen is to have a simple search and results page which allows users to enter criteria and see the results in a grid. Common features like sorting, filtering, and pagination make the process of finding results easier, and users have come to expect that behavior. The nature of the search input, and how you allow the users to specify criteria, has an impact on how the queries perform, and how easy it is to tune or cache them. At a certain point in a feature like this, users start to complain, and someone has to 'take a look at why the search is getting so slow'. The queries are reviewed, changes are made, a few seconds are shaved off, and that's usually where it ends, but there's more to it than that.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&amp;nbsp; &amp;nbsp;What are you looking for?&lt;/span&gt;&lt;br /&gt;
When a developer tests a search/results page for performance, they would tend to try a few different criteria, use a wide date range, and click around the sorting and pagination links, but for a real user, the flow doesn't end there. Most of the time that I've seen users complaining about a slow search page, its not because of the initial search, but because of how they use it. A user might fire off a search view the results, sort/filter, then click to see the full details of one record, go back to the results page (which might fire off the full query again), look at a few more individual records, and continually bounce back and forth between the details and results list. To this user, the search might seem slow, not because of how it performs initially, but because of how long it is taking them to find what they are looking for, and the process of going back and forth. Asking them how they use it, and actually watching what they do, you will see opportunities to improve the design and match their flow.&lt;br /&gt;
&lt;br /&gt;
A few common search workflows I have seen, each resulting in different interface features to make things easier:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Collect and Compare&lt;/b&gt;: A user may issue different queries to find specific items and compare them&lt;br /&gt;
"I'm looking to see if there is a difference for this client at their midwest branch vs. east coast"&lt;br /&gt;
&lt;i&gt;Design&lt;/i&gt;: Allow the user to 'keep' or 'favorite' particular records, view them in sequence or side by side, or save them in a named 'group' for later review.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Filter and exclude&lt;/b&gt;: A user may start broad, but continue to narrow down to a set of records. They may want to 'remove' specific records from the results.&lt;br /&gt;
"I need to find all of the accounts that are past due in this region, but not the 3 that are managed by Mary"&lt;br /&gt;
&lt;i&gt;Design&lt;/i&gt;: Allow a user to 'remove' results from the query, or at least have them hidden from the display.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Routine Checkup&lt;/b&gt;: A user may fire the same search at regular intervals to see if anything has changed, top 5 results, list of work to do, etc.&lt;br /&gt;
"The rates are updated twice a day, so I come in and fire off my search to see who's in the top 10 in the morning and in the afternoon"&lt;br /&gt;
&lt;i&gt;Design&lt;/i&gt;: Allow a user to save a query like this, and have it become part of a dashboard or notification email.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Alert! : &lt;/span&gt;A user may run a query once a week to look for an infrequent but important business issue.&lt;br /&gt;
"I have to check for duplicate orders."&lt;br /&gt;
"I have to fax orders with a coupon code to corporate because we can't do split billing yet"&lt;br /&gt;
&lt;i&gt;Design&lt;/i&gt;: This could be done as an order validation routine. Don't allow orders of this type, or send out the correct email notification immediately upon creation, anything you can do to codify the business logic and allow the user to focus on higher value work.&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Sometimes it's the little things&lt;/span&gt;&lt;br /&gt;
One good way to understand what your user's are doing with your search, without having to ask each one of them, is to allow them to save a search, give it a name, a brief description, and allow them to share it with others of equal permission/role. Letting them save their search will go a long way towards making the app seem faster, as they no longer need to fill in the search criteria, or re-run the search when they forget a checkbox. You may also discover, by analyzing the saved searches, that there is a pattern or grouping of searches that could be improved or cached. You may discover a category of searches that several users are interested in, and instead of having them all log in, fumble through the search input process, and all peg the server at the same time on monday morning, you could run that query once, store the results, show it on the dashboard, fire off the daily emails, and lower the amount of work the system is doing, while increasing its value to the users.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Whenever I do a performance analysis, my workflow tends to be:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Reviewing the log files&lt;/li&gt;
&lt;li&gt;Analyzing web page performance&lt;/li&gt;
&lt;li&gt;Analyzing application setup and performance&lt;/li&gt;
&lt;li&gt;Reviewing the Database setup and tuning the slow queries&lt;/li&gt;
&lt;li&gt;Reviewing the performance of the loaded page (javascript, ajax, rendering, etc)&lt;/li&gt;
&lt;li&gt;* Looking for design changes that will lead to a faster user experience *&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
So try to sketch out the full workflow of your users, and look for ways to simplify the steps they take, have the system do more work for them, and let them focus on doing MORE of what you want them to do.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-8288484396376245838?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Pt4qSMoYoAShEIcpfxlU5EpaMhY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Pt4qSMoYoAShEIcpfxlU5EpaMhY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Pt4qSMoYoAShEIcpfxlU5EpaMhY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Pt4qSMoYoAShEIcpfxlU5EpaMhY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=GY0DRr3M7F0:kiXdj87Ol0M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=GY0DRr3M7F0:kiXdj87Ol0M:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=GY0DRr3M7F0:kiXdj87Ol0M:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=GY0DRr3M7F0:kiXdj87Ol0M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=GY0DRr3M7F0:kiXdj87Ol0M:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/GY0DRr3M7F0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/8288484396376245838/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/10/improving-application-performance-by.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/8288484396376245838?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/8288484396376245838?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/GY0DRr3M7F0/improving-application-performance-by.html" title="Improving application Performance by tracking user Workflow" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2011/10/improving-application-performance-by.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkECRXoycCp7ImA9WhdaGE8.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-5913074982880090674</id><published>2011-10-05T11:11:00.000-05:00</published><updated>2011-10-28T11:51:04.498-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-28T11:51:04.498-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="freshbooks" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><category scheme="http://www.blogger.com/atom/ns#" term="script" /><category scheme="http://www.blogger.com/atom/ns#" term="invoice" /><category scheme="http://www.blogger.com/atom/ns#" term="freelance" /><title>Quick Script: Freshbooks sum of total hours</title><content type="html">I like freshbooks, but for some reason they don't show the total number of hours at the bottom of the invoice, which has &lt;a href="http://community.freshbooks.com/forums/viewtopic.php?id=7896"&gt;been a complaint for awhile.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://gist.github.com/1264854"&gt;Here is a quick script&lt;/a&gt;&amp;nbsp;I wrote that returns the total for billable and nonbillable hours. Its not perfect, and its likely to break if they change the structure of the page, but its a start.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="white-space: pre-wrap; word-wrap: break-word;"&gt;//take this script and place it in your firebug or javascript console (when you are on the invoice edit page)
//it will segment billable and non-billable (0.00) and total them up (could be improved to group by rate)&lt;/pre&gt;
&lt;pre style="white-space: pre-wrap; word-wrap: break-word;"&gt;var total=0;
function add_them(index, e){
  var num = parseFloat($(e).val());
  if (!isNaN(num)) {
   total += num; 
  }
}

//find trs with td and a non-zero or empty hourly rate
var billable = $('tr').has('td.editable').has('input[name="unit_cost[]"][value!="0.00"][value!=""]');
var total=0; //zero out reusable variable
//within that group, go find the hours and total them up
billable.find('input[name="qty[]"]').each(add_them);
var bill_total = total; //copy value before running the next calc

//find trs with td and a zero value hourly rate
var non_billable = $('tr').has('td.editable').has('input[name="unit_cost[]"][value="0.00"]');
var total=0; //zero out reusable variable
non_billable.find('input[name="qty[]"]').each(add_them);
var nonbill_total = total;

//print it out if console is available
if(this.console){
console.log('Billable hours total: ' + bill_total);
console.log('Non-Billable hours total: ' + nonbill_total);
}&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-5913074982880090674?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/g_K0sQ0f8j5YSFzKhrvp88garLg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/g_K0sQ0f8j5YSFzKhrvp88garLg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/g_K0sQ0f8j5YSFzKhrvp88garLg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/g_K0sQ0f8j5YSFzKhrvp88garLg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=zdO_V9T_c5g:JkHb2Z2EVUo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=zdO_V9T_c5g:JkHb2Z2EVUo:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=zdO_V9T_c5g:JkHb2Z2EVUo:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=zdO_V9T_c5g:JkHb2Z2EVUo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=zdO_V9T_c5g:JkHb2Z2EVUo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/zdO_V9T_c5g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/5913074982880090674/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/10/quick-script-freshbooks-sum-of-total.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/5913074982880090674?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/5913074982880090674?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/zdO_V9T_c5g/quick-script-freshbooks-sum-of-total.html" title="Quick Script: Freshbooks sum of total hours" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2011/10/quick-script-freshbooks-sum-of-total.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEQFRn88fip7ImA9WhdVEkQ.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-6410078056077335012</id><published>2011-09-17T16:46:00.000-05:00</published><updated>2011-09-17T16:51:57.176-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-17T16:51:57.176-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="windycityrails" /><category scheme="http://www.blogger.com/atom/ns#" term="mysql" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="chicagoruby" /><category scheme="http://www.blogger.com/atom/ns#" term="explain" /><category scheme="http://www.blogger.com/atom/ns#" term="postgres" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><title>Improving Web Page Performance WindyCityRails 2011</title><content type="html">&lt;b&gt;WindyCityRails 2011&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;This has been a great conference once again! Its so cool to see how the conference has grown over the last 4 years, and how the Chicago Rails community has grown.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;I had a lot of fun giving my talk, and got good feedback on &lt;a href="http://speakerrate.com/talks/8314-faster-page-performance"&gt;SpeakerRate&lt;/a&gt;. I was intimidated speaking after Dr. Nic, and before Tom Preston-Werner from Github, those are some heavyweight Rubyists!&amp;nbsp;
&lt;br /&gt;
&lt;br /&gt;
Here are my slides, please let me know if you have any questions, I will answer them if I can. (there's always something that I wish I could have covered more)

&lt;br /&gt;
&lt;div id="__ss_9300600" style="width: 425px;"&gt;
&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/johnny_zebra/windycityrails-page-performance" title="Windycityrails page performance"&gt;Windycityrails page performance&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse9300600" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=windycityrailspageperformance-110917163453-phpapp01&amp;stripped_title=windycityrails-page-performance&amp;userName=johnny_zebra" /&gt;

&lt;param name="allowFullScreen" value="true"/&gt;

&lt;param name="allowScriptAccess" value="always"/&gt;

&lt;embed name="__sse9300600" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=windycityrailspageperformance-110917163453-phpapp01&amp;stripped_title=windycityrails-page-performance&amp;userName=johnny_zebra" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;div style="padding: 5px 0 12px;"&gt;
View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/johnny_zebra"&gt;John McCaffrey&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-6410078056077335012?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tij4rabs-nO0njHbRXCeZlMwtdQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tij4rabs-nO0njHbRXCeZlMwtdQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tij4rabs-nO0njHbRXCeZlMwtdQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tij4rabs-nO0njHbRXCeZlMwtdQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=qHibyWRYa8U:xfPbSoak-9Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=qHibyWRYa8U:xfPbSoak-9Y:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=qHibyWRYa8U:xfPbSoak-9Y:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=qHibyWRYa8U:xfPbSoak-9Y:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=qHibyWRYa8U:xfPbSoak-9Y:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/qHibyWRYa8U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/6410078056077335012/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/09/windycityrails-2011-has-been-great.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/6410078056077335012?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/6410078056077335012?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/qHibyWRYa8U/windycityrails-2011-has-been-great.html" title="Improving Web Page Performance WindyCityRails 2011" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><georss:featurename>Chicago, IL, USA</georss:featurename><georss:point>41.8781136 -87.6297982</georss:point><georss:box>41.6889701 -87.94565519999999 42.0672571 -87.3139412</georss:box><feedburner:origLink>http://www.railsperformance.com/2011/09/windycityrails-2011-has-been-great.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8FRXw9fSp7ImA9WhdQEko.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-889250629407821044</id><published>2011-08-13T13:29:00.006-05:00</published><updated>2011-08-13T17:33:34.265-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-13T17:33:34.265-05:00</app:edited><title>IRB tips and Tricks</title><content type="html">&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;I love me some IRB!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Its such a great tool and something I have open constantly.&lt;br /&gt;
&lt;br /&gt;
I use it for:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Quick syntax checking&lt;/li&gt;
&lt;li&gt;File scripting&lt;/li&gt;
&lt;li&gt;Regular expression&lt;/li&gt;
&lt;li&gt;Checking the 'state of things' in production or staging environments&lt;/li&gt;
&lt;/ol&gt;
One small change I should point out is that in my ~/.irbrc, I have this little piece that will load another .irbrc file if it is present in the project, so I can add additional methods to the project, given its ruby/rvm/gems setup.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;    load '.irbrc' if File.exists?('.irbrc')
&lt;/pre&gt;
&lt;br /&gt;
&lt;div id="__ss_8844903" style="width: 425px;"&gt;
&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/johnny_zebra/irb-tips-and-tricks" title="Irb Tips and Tricks"&gt;Irb Tips and Tricks&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse8844903" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=irbtricks2-110813161508-phpapp01&amp;stripped_title=irb-tips-and-tricks&amp;userName=johnny_zebra" /&gt;

&lt;param name="allowFullScreen" value="true"/&gt;

&lt;param name="allowScriptAccess" value="always"/&gt;

&lt;embed name="__sse8844903" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=irbtricks2-110813161508-phpapp01&amp;stripped_title=irb-tips-and-tricks&amp;userName=johnny_zebra" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;div style="padding: 5px 0 12px;"&gt;
View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/johnny_zebra"&gt;John McCaffrey&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;
Tons of good Resources:&lt;br /&gt;
&lt;ul class="ul1"&gt;
&lt;ul class="ul1"&gt;
&lt;li class="li1"&gt;&lt;span class="s1"&gt;&lt;/span&gt;&lt;span class="s2"&gt;Why’s IRB Guide &lt;a href="http://bit.ly/_why_irb"&gt;&lt;span class="s3"&gt;http://bit.ly/_why_irb&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="li1"&gt;&lt;span class="s1"&gt;&lt;a href="http://cheat.errtheblog.com/s/rails_console"&gt;&lt;span class="s4"&gt;http://cheat.errtheblog.com/s/rails_console&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="li1"&gt;&lt;span class="s1"&gt;&lt;a href="http://bit.ly/thoughtbot-irb"&gt;&lt;span class="s4"&gt;http://bit.ly/thoughtbot-irb&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="li1"&gt;&lt;span class="s1"&gt;&lt;a href="http://bit.ly/tagaholic-irb"&gt;&lt;span class="s4"&gt;http://bit.ly/tagaholic-irb&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="li1"&gt;&lt;span class="s1"&gt;&lt;a href="http://bit.ly/stackoverflow-irb"&gt;&lt;span class="s4"&gt;http://bit.ly/stackoverflow-irb&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="li1"&gt;&lt;span class="s1"&gt;&lt;span class="s4"&gt;&lt;a href="http://bit.ly/pivotal-debug-irb"&gt;http://bit.ly/pivotal-debug-irb&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;










&lt;/li&gt;
&lt;li&gt;&lt;a href="http://railscasts.com/episodes/48-console-tricks"&gt;&lt;span class="s2"&gt;http://railscasts.com/episodes/48-console-tricks&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://slash7.com/2006/12/21/secrets-of-the-rails-console-ninjas/"&gt;&lt;span class="s2"&gt;http://slash7.com/2006/12/21/secrets-of-the-rails-console-ninjas&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://errtheblog.com/posts/24-irb-mix-tape"&gt;&lt;span class="s2"&gt;http://errtheblog.com/posts/24-irb-mix-tape&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/"&gt;&lt;span class="s2"&gt;http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://vimcasts.org/episodes/running-vim-within-irb"&gt;http://vimcasts.org/episodes/running-vim-within-irb&lt;/a&gt;&lt;/li&gt;
&lt;ul class="ul1"&gt;&lt;ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-889250629407821044?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zK8rRdjt3v6sPfGC6mD4E-jBAs4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zK8rRdjt3v6sPfGC6mD4E-jBAs4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zK8rRdjt3v6sPfGC6mD4E-jBAs4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zK8rRdjt3v6sPfGC6mD4E-jBAs4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=3JLiT3ya_p4:mEBzIgaPxkM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=3JLiT3ya_p4:mEBzIgaPxkM:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=3JLiT3ya_p4:mEBzIgaPxkM:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=3JLiT3ya_p4:mEBzIgaPxkM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=3JLiT3ya_p4:mEBzIgaPxkM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/3JLiT3ya_p4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/889250629407821044/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/08/irb-tips-and-tricks.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/889250629407821044?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/889250629407821044?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/3JLiT3ya_p4/irb-tips-and-tricks.html" title="IRB tips and Tricks" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.railsperformance.com/2011/08/irb-tips-and-tricks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8FQXo4fyp7ImA9WhdRE0U.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-1391411688945996911</id><published>2011-08-03T10:53:00.000-05:00</published><updated>2011-08-03T10:53:30.437-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-03T10:53:30.437-05:00</app:edited><title>13 Great Application Performance tuning blogs to follow</title><content type="html">Here's a list of the Performance blogs that I follow:&lt;br /&gt;
&lt;script type="text/javascript" src="https://www.google.com/reader/ui/publisher-en.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript" src="https://www.google.com/reader/public/javascript-sub/user/04786489666004867675/bundle/performance-feeds?callback=GRC_p(%7Bc%3A%22blue%22%2Ct%3A%22My%20%5C%22performance-feeds%5C%22%20Bundle%22%2Cb%3A%22true%22%7D)%3Bnew%20GRC"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I put them all together in a bundle, so if you subscribe to this, you'll get new feeds when I add them.&lt;br /&gt;
&lt;a href="http://bit.ly/perf-feeds"&gt;http://bit.ly/perf-feeds&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-1391411688945996911?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2L29BN-TV9KKH5i4FDC3BIbv2rI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2L29BN-TV9KKH5i4FDC3BIbv2rI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2L29BN-TV9KKH5i4FDC3BIbv2rI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2L29BN-TV9KKH5i4FDC3BIbv2rI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=wJxDvncSyxo:9XbztVqaIIs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=wJxDvncSyxo:9XbztVqaIIs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=wJxDvncSyxo:9XbztVqaIIs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=wJxDvncSyxo:9XbztVqaIIs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=wJxDvncSyxo:9XbztVqaIIs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/wJxDvncSyxo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/1391411688945996911/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/08/13-great-application-performance-tuning.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/1391411688945996911?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/1391411688945996911?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/wJxDvncSyxo/13-great-application-performance-tuning.html" title="13 Great Application Performance tuning blogs to follow" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2011/08/13-great-application-performance-tuning.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04NQXk5eCp7ImA9WhZVGUk.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-572206983980577814</id><published>2011-05-24T12:52:00.004-05:00</published><updated>2011-06-01T10:26:30.720-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-01T10:26:30.720-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="conference" /><category scheme="http://www.blogger.com/atom/ns#" term="railsconf" /><category scheme="http://www.blogger.com/atom/ns#" term="eventmachine" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="heroku" /><category scheme="http://www.blogger.com/atom/ns#" term="photos" /><category scheme="http://www.blogger.com/atom/ns#" term="postgres" /><category scheme="http://www.blogger.com/atom/ns#" term="freelance" /><title>Railsconf 2011 notes, pictures, and review</title><content type="html">RailsConf 2011: Simply Amazing!&lt;br /&gt;
&lt;br /&gt;
Last year was my first Railsconf, and while I learned a ton, I think I made a lot of 'first timer' conference mistakes like:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Not reading up on the sessions, presenters, recent developments and blogs in advance&lt;/li&gt;
&lt;li&gt;Not maximizing my networking time (ie. spent too much time with people I already know)&lt;/li&gt;
&lt;li&gt;Not leaving a session that wasn't a good fit because I felt awkward about getting up&lt;/li&gt;
&lt;li&gt;Not having enough business cards&lt;/li&gt;
&lt;li&gt;Not having recent blog or twitter posts to encourage someone to follow me&lt;/li&gt;
&lt;li&gt;Not staying out late and meeting more people&lt;/li&gt;
&lt;li&gt;Not getting up early and getting to the keynotes on time&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;So this year I vowed to do a better job, and other than the conflict between staying out late, and getting up early, I felt I tackled all of my concerns pretty well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I tried to push myself to be more outgoing and less socially awkward than I normally am. Which in some cases meant I just had to walk up to a group of people and ask what they were chatting about, what they found interesting so far, or what they were here to learn. For the first 4mins of any of these 'interrupting intros' it would be rough. I wish I could take a picture of it, the crinkled nose, furrowed brow, 'who the hell are you?' look. I'm very sensitive to facial gestures, and have a hard time ignoring the wealth of feedback I get from their physical output, but I've learned that you just need to get past it, otherwise you'll be sitting in the corner by yourself.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I was very friendly. Gregarious, but not obnoxious, and did my best to add something immediately relevant to whatever they were discussing, but still I got these mean scowls for the first few minutes. I pressed on, ignoring the scowls, determined to make a meaningful connection, and I'm happy to say that it really paid off.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;About 10-15mins into almost every one of these conversations we'd get into something interesting and I'd share some advice, perhaps some sites or a blog post they should check out, and then I'd get asked for my business card. I think I gave out 30 business cards to people that directly asked for them, which is more than I've ever done before. And I've already been contacted by 2 of them for potential projects. (I'm not trying to brag, just trying to say that its worth pushing yourself to be more social, walk up to another group and just start a conversation. They are Rails developers after all, you certainly have something you can chat about)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Sunday:&lt;/div&gt;&lt;div&gt;Found my rails peeps at Pratt St. Alehouse&lt;/div&gt;&lt;div&gt;Closed the place down chatting with Steve Smith from OrderedList&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Monday:&lt;/div&gt;&lt;div&gt;While in the Rails 3 upgrade, I actually upgraded an existing app from 2.3.5 to 2.3.11, and am finishing up the 3.0.7 upgrade now&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
I got to chat with some of the team from Heroku at the booth, and gushed about how much I love it. I also pointed them to &lt;a href="http://ontwik.com/rails/future-is-here-rails-and-cloud-ecosystem/"&gt;a great screencast&lt;/a&gt; that shows how to monitor heroku under load, and scale up more dynos to get better response time. They added me to the Heroku Beta program, so I can start testing out new features. (but won't be able to blog about them initially)&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;The &lt;a href="http://zfer.us/yrKfS" target="blank"&gt;Rails best practices tutorial&lt;/a&gt; was awesome, and I recommend everyone should go to codeschool.com and sign up for Rails for Zombies and Rails Best Practices. Its very cool, and I expect to see a lot more courses coming out of it. Pure awesomeness!  (disclosure: they have a referral program, so I think I get some kind of codeschool dollars or something...I mostly just want to see the tracking part)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Went to Ignite rails conf (gave my extra ticket to Ryan Bates of Railscasts.com...a small token of thanks for all the stuff I've learned from him). &amp;nbsp;The talks were great, and showed a side of our community that goes beyond technical concerns and is passionate about giving, teaching, leadership, and making a difference.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Great party given by EngineYard at Max's Taphouse. &amp;nbsp;Met some really cool people, closed the place down, and grabbed a slice of decent baltimore pizza at 2 in the morning.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Tuesday:&lt;/div&gt;&lt;div&gt;I attended&lt;/div&gt;&lt;div&gt;Credit card processing talk by Living Social&lt;/div&gt;&lt;div&gt;Spree&amp;nbsp;&lt;/div&gt;&lt;div&gt;Geospace your rails app&lt;/div&gt;&lt;div&gt;25 deployment tips&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Didn't stay out late, as I wanted to finish up my lightning talk, and also be fresh at least one morning.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Wednesday:&lt;/div&gt;&lt;div&gt;Inside groupon&lt;/div&gt;&lt;div&gt;scaling with friends from zynga&lt;/div&gt;&lt;div&gt;Scalable servers with Event Machine by David Troy&lt;/div&gt;&lt;div&gt;I gave a lightning talk on 'Freelancing on Rails' which seemed pretty well received, even though the majority of the lightning talks were more code and tech focused&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Based on the feedback from my lightning talk, I organized a 'Birds of a feather' roundtable discussion on freelancing and managing side projects. It was great because there were people with varying levels of experience and client types, some coming from java/.net, some that do a side project here and there, and others that don't have a full time job, just a full plate of side projects.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I referenced the very interesting video called &lt;a href="http://vimeo.com/22053820"&gt;"F@ck you, pay me", by Mike Monteiro&lt;/a&gt;, which lays out some good rules for freelancers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I then stayed out way too late after the github party, as you can see in the pictures below. (and I regret that I didn't at least drop in on the music jam session. that was a mistake)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Thursday:&lt;/div&gt;&lt;div&gt;missed the first session&lt;/div&gt;&lt;div&gt;Toolkit choices&lt;/div&gt;&lt;div&gt;Emrubyconf (all event machine stuff)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;It was a great conference. Very hard to go back to work, and use old stuff when I want to try out all this new stuff, but I love to see how things are moving forward in this space. The Rails community is awesome and I'm so glad to be a part of it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Here are the pictures I took this year:&lt;/div&gt;&lt;embed type="application/x-shockwave-flash" src="https://picasaweb.google.com/s/c/bin/slideshow.swf" width="600" height="400" flashvars="host=picasaweb.google.com&amp;captions=1&amp;noautoplay=1&amp;hl=en_US&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Fjohn.mccaffrey%2Falbumid%2F5610304752887039073%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-572206983980577814?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5RmTE0_PLGoxc9AId8-rkx9FvNU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5RmTE0_PLGoxc9AId8-rkx9FvNU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5RmTE0_PLGoxc9AId8-rkx9FvNU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5RmTE0_PLGoxc9AId8-rkx9FvNU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=I-XNoz4Y9k0:QAwH0jSyQSc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=I-XNoz4Y9k0:QAwH0jSyQSc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=I-XNoz4Y9k0:QAwH0jSyQSc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=I-XNoz4Y9k0:QAwH0jSyQSc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=I-XNoz4Y9k0:QAwH0jSyQSc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/I-XNoz4Y9k0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/572206983980577814/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/05/railsconf-2011-notes-pictures-and.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/572206983980577814?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/572206983980577814?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/I-XNoz4Y9k0/railsconf-2011-notes-pictures-and.html" title="Railsconf 2011 notes, pictures, and review" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.railsperformance.com/2011/05/railsconf-2011-notes-pictures-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMNQX49eSp7ImA9WhZWF0g.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-3444178496522408282</id><published>2011-05-18T16:09:00.001-05:00</published><updated>2011-05-18T16:18:10.061-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-18T16:18:10.061-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="railsconf" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="lightning" /><category scheme="http://www.blogger.com/atom/ns#" term="freelance" /><title>What I've learned: Freelancing and side projects on Rails</title><content type="html">I had a blast giving this talk in a short period of time at the Railsconf 2011, along with 16 other people that had to fly through their talk in 5min.&lt;br /&gt;
&lt;br /&gt;
There is a &lt;a href="http://bit.ly/gig-survey"&gt;survey of rate info&lt;/a&gt; that the attendees filled out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="width:425px" id="__ss_8017079"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/johnny_zebra/freelancing-and-sideprojects-on-rails" title="Freelancing and side-projects on Rails"&gt;Freelancing and side-projects on Rails&lt;/a&gt;&lt;/strong&gt; &lt;iframe src="http://www.slideshare.net/slideshow/embed_code/8017079" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"&gt;&lt;/iframe&gt; &lt;div style="padding:5px 0 12px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/johnny_zebra"&gt;John McCaffrey&lt;/a&gt; &lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-3444178496522408282?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/smYUZIBhtJWGSSz2C8FFODHHOfY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/smYUZIBhtJWGSSz2C8FFODHHOfY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/smYUZIBhtJWGSSz2C8FFODHHOfY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/smYUZIBhtJWGSSz2C8FFODHHOfY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=K8iVF0MXY34:XCDC2iSt_20:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=K8iVF0MXY34:XCDC2iSt_20:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=K8iVF0MXY34:XCDC2iSt_20:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=K8iVF0MXY34:XCDC2iSt_20:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=K8iVF0MXY34:XCDC2iSt_20:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/K8iVF0MXY34" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/3444178496522408282/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/05/what-ive-learned-freelancing-and-side.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/3444178496522408282?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/3444178496522408282?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/K8iVF0MXY34/what-ive-learned-freelancing-and-side.html" title="What I've learned: Freelancing and side projects on Rails" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.railsperformance.com/2011/05/what-ive-learned-freelancing-and-side.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAGRXc-eip7ImA9WhZWE0w.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-2690164717548758205</id><published>2011-05-13T14:07:00.001-05:00</published><updated>2011-05-13T14:08:44.952-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-13T14:08:44.952-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rvm gemset rubymine i18n" /><title>Fixing Rails error format '{{attribute}} {{message}}' caused by i18n and Rubymine RVM issue</title><content type="html">&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: left;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-qotBfsLMRFk/Tc2ApdOnWgI/AAAAAAAAOGU/ykEi-gVC8cU/s1600/rvm_gemset_issue.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="360" src="http://2.bp.blogspot.com/-qotBfsLMRFk/Tc2ApdOnWgI/AAAAAAAAOGU/ykEi-gVC8cU/s640/rvm_gemset_issue.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;File &amp;gt; Settings &amp;gt; Ruby SDK and Gems&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;I've been using &lt;a class="zem_slink" href="http://www.jetbrains.com/ruby" rel="homepage" title="RubyMine"&gt;RubyMine&lt;/a&gt; as my main Rails editor since the minute Netbeans discontinued their support of Rails, and I've got to say I've been loving it. I knew that JetBrains made good editors, but I didn't know it would be this good. Its been worth every penny, as it helps me get up to speed on a project faster, and its rvm integration is crucial for ensuring I'm running in exactly the same env as the command line (netbeans did not play with rvm very well)&lt;br /&gt;
&lt;br /&gt;
I recently ran into an issue when running a rails 2.3.5 project. &amp;nbsp;I started getting active record error messages returned in the format&amp;nbsp;&lt;span class="Apple-style-span" style="color: #141414; font-family: 'Lucida Grande'; font-size: 11px;"&gt;"&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #141414; font-family: 'Lucida Grande'; font-size: 11px;"&gt;&lt;b&gt;{{count}} errors prohibited this {{model}} from being saved", and "{{attribute}} {{message}}". &amp;nbsp;&lt;/b&gt;&lt;/span&gt;I had seen this kind of thing before, and figured I must have installed some Rails 3 gems into this rvm (I had just started up a new side project on Rails 3, and must not have been paying attention to which terminal window I was in).&lt;br /&gt;
&lt;br /&gt;
Sure enough there were a few Rail 3 gems, and i18n 0.5.0 in particular was &lt;a href="http://stackoverflow.com/questions/4370503/why-doesnt-rails-errors-full-messages-replace-attribute-and-message-variables/4475246#4475246"&gt;reported to be the main culprit&lt;/a&gt;. I removed that version of the i18n gem, fired up the server from the command line, and verified that my error messages were displaying correctly.&lt;br /&gt;
&lt;br /&gt;
But when I launched the app from Rubymine, it was still loading i18n 0.5.0. &amp;nbsp;A little poking around later, and I think that what happened is that I had this project in my default ree 1.8.7 gemset, and ree-1.8.7 was available as the sdk in rubymine, but once I added a new gemset to ree, rubymine no longer displayed the default, or "rubymine loses default rvm gemset" once a named gemset is added.&lt;br /&gt;
&lt;br /&gt;
To fix this, it seemed like I just needed a named gemset for these gems, but I didn't want to install them all again, I just wanted to copy them. &lt;a href="http://beginrescueend.com/gemsets/copying/"&gt;According to the documentation&lt;/a&gt;, it shouldn't be hard, but I wasn't sure about the default unnamed gemset, because even when calling 'rvm gemset list' it wouldn't show that there was a default, or that I was currently using it.&lt;br /&gt;
&lt;br /&gt;
Here's what worked for me:&lt;br /&gt;
rvm gemset copy ree-1.8.7-2010.02 ree-1.8.7-2010.02@proj_gemset&lt;br /&gt;
&lt;br /&gt;
When I hopped back into Rubymine, I saw that ree with that gemset was now available, and set it as the default for that project. (which is available from File &amp;gt; Settings &amp;gt; Ruby SDK and Gems. &amp;nbsp;Which took me forever to find)&lt;br /&gt;
&lt;br /&gt;
&lt;style type="text/css"&gt;
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 11.0px 'Lucida Grande'; color: #141414}
&lt;/style&gt;     &lt;br /&gt;
&lt;div class="zemanta-pixie" style="height: 15px; margin-top: 10px;"&gt;&lt;img alt="" class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=969d1394-38f4-43d9-a15e-79302990de42" style="border: none; float: right;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-2690164717548758205?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/UZLwHnZhA9Gbr9k6D1xKVT71-lM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UZLwHnZhA9Gbr9k6D1xKVT71-lM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/UZLwHnZhA9Gbr9k6D1xKVT71-lM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UZLwHnZhA9Gbr9k6D1xKVT71-lM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=VRNDvs8lDNQ:DvCzU9wVftw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=VRNDvs8lDNQ:DvCzU9wVftw:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=VRNDvs8lDNQ:DvCzU9wVftw:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=VRNDvs8lDNQ:DvCzU9wVftw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=VRNDvs8lDNQ:DvCzU9wVftw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/VRNDvs8lDNQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/2690164717548758205/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/05/fixing-rails-error-format-attribute.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/2690164717548758205?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/2690164717548758205?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/VRNDvs8lDNQ/fixing-rails-error-format-attribute.html" title="Fixing Rails error format '{{attribute}} {{message}}' caused by i18n and Rubymine RVM issue" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-qotBfsLMRFk/Tc2ApdOnWgI/AAAAAAAAOGU/ykEi-gVC8cU/s72-c/rvm_gemset_issue.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2011/05/fixing-rails-error-format-attribute.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQFQHgzeCp7ImA9WhZTF0k.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-616495055738198772</id><published>2011-03-18T15:31:00.064-05:00</published><updated>2011-03-21T15:45:11.680-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-21T15:45:11.680-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="captcha" /><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="heroku" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><category scheme="http://www.blogger.com/atom/ns#" term="rails_xss" /><category scheme="http://www.blogger.com/atom/ns#" term="rmagick" /><title>Rails Captcha plugins</title><content type="html">&lt;b&gt;Captcha on Rails&lt;/b&gt;&lt;br /&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;div class="zemanta-img separator zemanta-action-dragged" style="clear: both; text-align: center;"&gt;&lt;a href="http://commons.wikipedia.org/wiki/File:RecaptchaLogo.svg" style="display: block; margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="The logo of reCAPTCHA" height="111" src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/ad/RecaptchaLogo.svg/300px-RecaptchaLogo.svg.png" style="border: none; font-size: 0.8em;" width="200" /&gt;&lt;/a&gt;&lt;span class="zemanta-img-attribution" style="clear: both; margin-left: 1em; margin-right: 1em;"&gt;Image via &lt;a href="http://commons.wikipedia.org/wiki/File:RecaptchaLogo.svg"&gt;Wikipedia&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;I needed to implement captcha to protect a 'forgot password?' form on a financial site this week, and I went through the various options to see what worked.&lt;br /&gt;
&lt;br /&gt;
The app I'm on is rails 2.3.5, so that's what my testing was under.&lt;br /&gt;
&lt;br /&gt;
When evaluating plugins and tools, I find it easier to start with a clean project, and try it out without any interference from the peculiarities of a full blown app. This allows me to follow the steps in cookie-cutter fashion, see how it works, and push a demo app up to heroku so that I can get some feedback from my clients. Its almost always faster for me to go through the tutorial, follow the basic steps, and push an app up to heroku, than it is for me to implement the tool in my real app, add appropriate tests, wait for the build, deploy to a test env, etc. Deploying to heroku allows me to get the proposed feature in the hands of my clients very quickly, and that feedback can save me a ton of time (particularly when I find out that there are some additional constraints that require me to change direction)&lt;br /&gt;
&lt;br /&gt;
My requirements were:&lt;br /&gt;
&amp;nbsp;"add a captcha to the forgot password page"&lt;br /&gt;
&lt;br /&gt;
I looked on &lt;a href="http://www.ruby-toolbox.com/categories/rails_captcha.html"&gt;ruby-toolbox&lt;/a&gt; to see what plugins were being used and had good traction, and narrowed it to these three:&lt;br /&gt;
&lt;br /&gt;
Simple-Captcha&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: #333333; font-family: verdana, arial, helvetica, sans-serif; font-size: 13px; line-height: 18px;"&gt;&lt;a href="http://expressica.com/simple_captcha/" style="color: black;"&gt;http://expressica.com/simple_captcha&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;requires rmagick to create the image&lt;/li&gt;
&lt;li&gt;requires db:migrate to persist the keyed answer&lt;/li&gt;
&lt;li&gt;works well, easy enough to change&lt;/li&gt;
&lt;/ol&gt;reCaptcha (sponsored by google)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://www.google.com/recaptcha"&gt;http://www.google.com/recaptcha&lt;/a&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;commonly used, well tested, looks professional&lt;/li&gt;
&lt;li&gt;requires outbound http call, (may have to deal with proxies)&lt;/li&gt;
&lt;li&gt;can&amp;nbsp;handle ssl&lt;/li&gt;
&lt;li&gt;can play audio if text is too hard&lt;/li&gt;
&lt;li&gt;expects String.html_safe (rails &amp;gt; 2.3.7), had to monkey patch a do nothing method&lt;/li&gt;
&lt;li&gt;has styling options, but I had problems getting it to look right in the form I was using&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;BrainBuster&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="https://github.com/rsanheim/brain_buster"&gt;https://github.com/rsanheim/brain_buster&lt;/a&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;doesn't make 3rd party outbound call&lt;/li&gt;
&lt;li&gt;doesn't require rmagick&lt;/li&gt;
&lt;li&gt;does require a db table to store a set of questions&lt;/li&gt;
&lt;li&gt;presents the user with a set of logic questions&lt;/li&gt;
&lt;li&gt;by default uses cookies to flag that a user has answered successfully, but that can be turned off to always challenge the user&lt;/li&gt;
&lt;li&gt;handles numeric to text conversion when a user answers 'five' or '5'&lt;/li&gt;
&lt;/ol&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Getting started&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
I didn't think my client would want the 3rd party outbound call that reCaptcha uses, so&amp;nbsp;I&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&amp;nbsp;started with&amp;nbsp;simple-captcha, and created a quick demo on heroku (15mins reading the docs/code/tests/blogs, 15mins create the app and deploy)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: ruby"&gt;script/plugin install svn://rubyforge.org/var/svn/expressica/plugins/simple_captcha 
  rake simple_captcha:setup  
  rake db:migrate

 #add to routes
   map.simple_captcha '/simple_captcha/:action', :controller =&amp;gt; 'simple_captcha'
   
 #add to application_controller
   include SimpleCaptcha::ControllerHelpers  
&lt;/pre&gt;&lt;br /&gt;
The client checked it out and got back to me that it looked good, and to go ahead and implement it in the app.&lt;br /&gt;
&lt;br /&gt;
Getting it to work in our actual app took longer than I expected.&lt;br /&gt;
First, we are using &lt;a href="https://github.com/NZKoz/rails_xss"&gt;rails_xss&lt;/a&gt;, to escape output to the page, and there was an issue with how helpers are registered as 'safe' (but only in development, where classes are reloaded).&lt;br /&gt;
A few 'Stack level too deep' and 'segmentation fault's later, and I saw where the problem was. (I needed to register this helper in an initializer, whereas my application helpers are registered in a way that handles the class reloading in development)&lt;br /&gt;
&lt;br /&gt;
The next issue was getting the cucumber tests to pass.&lt;br /&gt;
The key was that cucumber has access to the session, and could look up the captcha value via&lt;br /&gt;
&lt;pre class="brush: ruby"&gt;captcha = SimpleCaptchaData.get_data(session[:simple_captcha]).try(:value)
  And I fill in "#{captcha}" for "captcha"
&lt;/pre&gt;&lt;br /&gt;
I was surprised that none of my functional tests were failing, but it turns out that the verification method is set to return true when running in the test env, so I added a few tests to verify the permutations that we don't cover in cucumber.&lt;br /&gt;
&lt;br /&gt;
I checked everything in, the build passed, and I was back to whatever I was doing before that landed in my lap...except, I wasn't quite finished. Turns out that rmagick/imagemagick is a pain to get working on windows, and several of the developers on the team are on windows, so it was time to look at another solution.&lt;br /&gt;
&lt;br /&gt;
I did get a chance to use the &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-revert.html"&gt;git revert&lt;/a&gt; command&lt;br /&gt;
&lt;pre class="brush: ruby"&gt;git revert 'hash of what you want to get rid of'
&lt;/pre&gt;&lt;br /&gt;
After some discussion with the team, it seemed like reCaptcha was the next logical tool to try, as its more well known, fully tested, and has the least requirements on the system. (doesn't even require a db table)&lt;br /&gt;
&lt;br /&gt;
The implementation was very quick (though there was an issue with String.html_safe), pushed out an update to heroku to get client feedback, and was working through some slight styling issues as I went into the morning standup.&lt;br /&gt;
&lt;pre class="brush: ruby"&gt;script/plugin install git://github.com/ambethia/recaptcha.git

# in config/initializers/recaptcha.rb
  
  #monkey patch to fix html_safe method
  class String
    def html_safe
      self
    end
  end

  # get an api key (free) from http://www.google.com/recaptcha
  ENV['RECAPTCHA_PUBLIC_KEY'] = 'youractualpublickey'
  ENV['RECAPTCHA_PRIVATE_KEY'] = 'youractualprivatekey'

# in the view, inside your form

&amp;lt;%= recaptcha_tags %&amp;gt;

# in the controller
 def update
    @user = User.find(params[:id])
    if verify_recaptcha
      if @user.update_attributes(params[:user])
        flash[:notice] = 'User was successfully updated.'
        redirect_to(@user) 
      else
        render :action =&amp;gt; "edit"
      end
    else  
      flash[:error] = 'Captcha no good' 
      render :action =&amp;gt; "edit"
    end
  end
&lt;/pre&gt;&lt;br /&gt;
But as I was mentioning in the standup that reCaptcha makes an outbound call, the team lead recalled that after a recent security review they were cutting back on anything making an outbound call, if possible.&lt;br /&gt;
&lt;br /&gt;
Which brings me to BrainBuster.&lt;br /&gt;
It doesn't require rmagick, or make an outbound call, the styling is simple, and it seems to work well.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: ruby"&gt;script/plugin install git://github.com/rsanheim/brain_buster.git
   script/generate brain_buster_migration
   rake db:migrate
 
 # in controller
   before_filter :create_brain_buster, :only =&amp;gt; [:edit]
   before_filter :validate_brain_buster, :only =&amp;gt; [:update]

 #method for handling the failure
  def render_or_redirect_for_captcha_failure
    render :action =&amp;gt; "show"
  end
 
 #in view (path to captcha view in plugins dir is added to controller for you)
  &amp;lt;%= render :partial =&amp;gt; '/captcha' %&amp;gt; 

&lt;/pre&gt;&lt;br /&gt;
I did run into a few things that I needed to change from the default, namely the fact that once you have passed the captcha, a cookie would be set that would lead to that user never being challenged again, which is not what I wanted, but was easy to address.&lt;br /&gt;
&lt;br /&gt;
There is also an issue in the fact that it implements the verification as a before filter which wasn't working for me as the page I'm working on was doing double duty as view and edit, so I stopped using the filters, and make the calls from within my action.&lt;br /&gt;
&lt;br /&gt;
Overall, its great that there are a lot of options for implementing captcha in a rails app. Depending on your requirements, you should be able to find something that works, and hopefully this post might make the decision process a little easier. &lt;br /&gt;
&lt;br /&gt;
Let me know how it works out for you.&lt;br /&gt;
&lt;br /&gt;
Here is the heroku deployment that I created to demo these plugins &lt;a href="http://simple-captcha-demo.heroku.com/" target="_blank"&gt;http://simple-captcha-demo.heroku.com/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I pushed up all the code to &lt;a href="https://github.com/jmccaffrey/rails_captcha_demo" target="_blank"&gt;github&lt;/a&gt;, so you can try it out for yourself.&lt;br /&gt;
&lt;br /&gt;
In the process of pushing up to github, I realized I didn't want my reCaptcha api key to be in the commit history, so after reading &lt;a href="http://help.github.com/removing-sensitive-data/" target="_blank"&gt;this&lt;/a&gt;, I ran:&lt;br /&gt;
&lt;pre class="brush: ruby"&gt;#get rid of the file
  git rm config/initializers/recaptcha.rb
  
  #go through history and rewrite
   git filter-branch --index-filter 'git rm --cached --ignore-unmatch config/initializers/recaptcha.rb' HEAD

  #now push up the rewritten history (dry-run first to see what might go wrong)
   git push --force --verbose --dry-run
   git push --force

  # and then within heroku command line
  heroku config:add RECAPTCHA_PUBLIC_KEY=my_public_key RECAPTCHA_PRIVATE_KEY=my_private_key

&lt;/pre&gt;&lt;br /&gt;
Thanks,&lt;br /&gt;
-John&lt;br /&gt;
&lt;br /&gt;
&lt;div class="zemanta-pixie" style="height: 15px; margin-top: 10px;"&gt;&lt;img alt="" class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=5fa3b323-cb65-48f7-a8b5-53606428748b" style="border: none; float: right;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-616495055738198772?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ltKwBvmOJwXWcGIUk0zp3gFw1yA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ltKwBvmOJwXWcGIUk0zp3gFw1yA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ltKwBvmOJwXWcGIUk0zp3gFw1yA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ltKwBvmOJwXWcGIUk0zp3gFw1yA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=GWVemFvGE6Q:4BMODSoT7B0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=GWVemFvGE6Q:4BMODSoT7B0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=GWVemFvGE6Q:4BMODSoT7B0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=GWVemFvGE6Q:4BMODSoT7B0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=GWVemFvGE6Q:4BMODSoT7B0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/GWVemFvGE6Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/616495055738198772/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2011/03/rails-captcha-plugins.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/616495055738198772?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/616495055738198772?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/GWVemFvGE6Q/rails-captcha-plugins.html" title="Rails Captcha plugins" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://www.railsperformance.com/2011/03/rails-captcha-plugins.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMHQn4-eCp7ImA9Wx9RFU8.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-8523976357746553923</id><published>2010-12-14T16:13:00.006-06:00</published><updated>2010-12-16T12:33:53.050-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-16T12:33:53.050-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="good_to_know" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="postgres" /><title>Good to know: week #1 (rails logging, postgres iLIKE, rubular.com, and more)</title><content type="html">&lt;div class="zemanta-img separator" style="clear: right;"&gt;&lt;a href="http://commons.wikipedia.org/wiki/File:Thinking_man.png" style="clear: right; display: block; float: right; margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="Thinking man" height="160" src="http://upload.wikimedia.org/wikipedia/commons/0/06/Thinking_man.png" style="border: none; font-size: 0.8em;" width="110" /&gt;&lt;/a&gt;&lt;span class="zemanta-img-attribution" style="clear: both; float: right; margin-left: 1em; margin-right: 1em; width: 110px;"&gt;Image via &lt;a href="http://commons.wikipedia.org/wiki/File:Thinking_man.png"&gt;Wikipedia&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
I'm not blogging enough. &amp;nbsp;I have a lot of ideas for what I'd like to blog about, but I somehow build up each idea into a series of steps that would take 1-2hrs to complete, and I don't have 2hrs to spare at the moment.&lt;br /&gt;
&lt;br /&gt;
I'm going to try and just write more frequently, and lower the bar on what I'm writing about. I may not blow your mind with some completely unheard of performance tidbit, but hopefully I'll pique your interest and maybe even start a discussion.&lt;br /&gt;
&lt;br /&gt;
So here's a breakdown of stuff I probably should have known, or maybe I did and just forgot, but when I saw it this week, I said "Well, that's good to know".&lt;br /&gt;
&lt;h2&gt;Rails tips&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;When invoking rails code in Production, through a rake task, I wasn't getting any logging info. Turns out &lt;a href="http://earthcode.com/blog/2009/05/rails_script_runner_logging_cron.html"&gt;Rails doesn't autoflush&lt;/a&gt; the log in production, so I had to add 'Rails.logger.flush' at the end of my rake task, and voila I could see why a task was failing in prod. (permissions issue, of course!)&lt;/li&gt;
&lt;li&gt;(0..5).to_a &amp;nbsp;will give you an array with [0,1,2,3,4,5] &amp;nbsp;(helpful when playing around in irb and you need an array to test with)&lt;/li&gt;
&lt;li&gt;how to get a date in a file name from the command line:&amp;nbsp;"/path/to/my_file`date +\%Y\%m\%d`.txt"&lt;/li&gt;
&lt;li&gt;It can be handy to use factory_girl in script/console to easily create some test objects to play with, or seed your dev env for testing.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;iLIKE john on postgres:&lt;/li&gt;
&lt;ol&gt;&lt;li&gt;if you do something like this "where upper(first_name) like 'john%'", you won't be using an index on first_name, unless you also created it using upper(first_name), but you can instead just use &amp;nbsp;"first_name iLIKE 'john%'" to use a case insensitive match, and take advantage of your index.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;I also came across some code that was doing where upper(ssn) like '%123456789%'&lt;br /&gt;
which is not going to use an index because of the upper, and is going to be slower than it needs to be because when there are 9 digits in an ssn, there is no need to do a 'like'&lt;br /&gt;
&lt;br /&gt;
the query I was working on went from 4500ms, to 1.7ms after a simple change to the query. (yes there was other stuff going on)&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;li&gt;I Got an ArgumentError (malformed format string - %') when putting a '%' in my like condition, &amp;nbsp;instead of&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{ :conditions =&amp;gt; [condition] }, just remove the [ ] and it won't try to format the '%'.&lt;/li&gt;
&lt;li&gt;I was copying a bunch of records from a heroku proof of concept app, down to a local copy to use as test data. This query: "insert into other_db.orders_table (select * from test_db.orders_table)" will copy all the data from one table to another, but the columns have to be in the exact same order (duh).&lt;/li&gt;
&lt;li&gt;I was doing some page performance improvements, moving the js to the bottom, combining the js files via Rails :cache, and testing in prod mode, to see that the files are combined and everything was working fine. &amp;nbsp;I started with the 2 easiest files, tested it, everything looked good, then added the last file and refreshed the browser to make sure it was picked up. I was about to check in when I saw some duplication that could be cleaned up. I moved some functions around, and cut out a ton of duplicate code from 3 pages, all the while verifying that my &lt;a href="http://www.highcharts.com/"&gt;highcharts&lt;/a&gt; charts were being rendered properly. &amp;nbsp;I noticed a misspelling I had made and was surprised that it didn't cause an error. Then it dawned on me, I was still running locally as 'production' env, and had been using the old file the whole time, and my refactoring of the javascript wasn't being picked up at all! I switched back to dev mode, saw a bunch of errors and then fixed them. &amp;nbsp;Before checking in, I decided to try prod mode again, and make sure the combined files were working. THEY WEREN'T!! &amp;nbsp;A few missing ';' made the javascript file not syntactically correct when it was combined with other files. (hmm, smells like lack of js tests around here)&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;h3&gt;Interesting sites (Rails, development, misc):&lt;/h3&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;a href="http://ruby5.envylabs.com/"&gt;Ruby5 podcast&lt;/a&gt;&amp;nbsp;&amp;nbsp;always great stuff&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;a href="http://blog.heroku.com/archives/2010/12/8/the_next_level/"&gt;heroku purchased by salesforce&lt;/a&gt;&amp;nbsp;I hope this turns out to be a good thing&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;a href="http://tech.fortune.cnn.com/2010/12/04/googles-groupon-groping-reveals-the-shifting-power-in-the-web-world/"&gt;Groupon says 'No deal' to Google&lt;/a&gt;&amp;nbsp;and what it says about Google, and Groupon&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;a href="http://www.simonecarletti.com/blog/2010/07/the-way-to-rails-3/"&gt;http://www.simonecarletti.com/blog/2010/07/the-way-to-rails-3/&lt;/a&gt;&amp;nbsp;its not as hard as it seems to be ready for Rails 3&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;a href="http://rubular.com/"&gt;rubular.com&lt;/a&gt; ruby regular expressions tester in your browser, faster and more informative than irb&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;a href="http://www.arailsdemo.com/"&gt;http://www.arailsdemo.com/&lt;/a&gt; great site that shows how to build up a rails app step by step. I was looking at it to see if there is any quick way to add acts_as_commentable and if there are any updates to that. (seems not much has changed)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;a href="http://skribit.com/"&gt;http://skribit.com/&lt;/a&gt; - blog plugin that lets people tell you what to write about. Exactly what I need! (please suggest a topic)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Entertainment&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;a href="http://armorgames.com/play/553/the-fancy-pants-adventure-world-2"&gt;fancypants adventure&lt;/a&gt;&amp;nbsp;- fun game as google chrome app, shows some nice physics and game play. Works offline.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;a href="http://www.vimeo.com/1084537"&gt;big buck bunny&lt;/a&gt; - very cool mini-movie showing off what the blender engine can do. (the bunny totally reminds me of Chris Farley)&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;a href="http://www.google.com/nexus/"&gt;http://www.google.com/nexus/&lt;/a&gt;&amp;nbsp;&amp;nbsp;New Android phone&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;a href="http://mashupbreakdown.com/"&gt;mashupbreakdown.com&lt;/a&gt; &amp;nbsp;'girl talk' all day music with a visual breakdown of what each sample is&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-8523976357746553923?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/i2DXF3O1jvBfvTAqYP354s039LE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/i2DXF3O1jvBfvTAqYP354s039LE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/i2DXF3O1jvBfvTAqYP354s039LE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/i2DXF3O1jvBfvTAqYP354s039LE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=DEs7q1ULkU8:nVuCnpJ0Ym0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=DEs7q1ULkU8:nVuCnpJ0Ym0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=DEs7q1ULkU8:nVuCnpJ0Ym0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=DEs7q1ULkU8:nVuCnpJ0Ym0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=DEs7q1ULkU8:nVuCnpJ0Ym0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/DEs7q1ULkU8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/8523976357746553923/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/12/good-to-know-week-1.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/8523976357746553923?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/8523976357746553923?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/DEs7q1ULkU8/good-to-know-week-1.html" title="Good to know: week #1 (rails logging, postgres iLIKE, rubular.com, and more)" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/12/good-to-know-week-1.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQEQXg6fSp7ImA9Wx9RFE8.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-2804662067353604633</id><published>2010-12-08T16:47:00.001-06:00</published><updated>2010-12-15T09:51:40.615-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-15T09:51:40.615-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="tuning" /><category scheme="http://www.blogger.com/atom/ns#" term="page speed" /><category scheme="http://www.blogger.com/atom/ns#" term="yslow" /><category scheme="http://www.blogger.com/atom/ns#" term="workflow" /><title>Performance tuning workflow</title><content type="html">Its hard to know where to start when it comes to speeding up your web app, but here's what I've found to work best for me.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Measure twice, cut once.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Its been said, "You can't improve what you can't measure" (Lord Kelvin...who knew a thing or two about measurement), and that's very true for performance tuning. Actually, I've recently run into a few things that I was absolutely positive would make things faster, but in looking at the numbers, it was clear that things were getting worse.&lt;br /&gt;
&lt;br /&gt;
Start with yslow, or page speed in your firefox browser. Measure your main page, even if its simple, and also go through your top 5 pages. Make note of your initial scores, so you can keep track of any improvement, but also make note of the recommendations and timings. In most cases you'll have front-end issues that need to be resolved.&lt;br /&gt;
&lt;br /&gt;
Looking at the waterfall diagram I'd see that the amount of time spent to pull down the html is actually pretty small, and the majority of the time was spent on everything after (js, images, css, ajax, etc).&lt;br /&gt;
&lt;br /&gt;
So we focus on the things that give us the biggest gain:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Make sure keep-alive is on&lt;/li&gt;
&lt;li&gt;Turn Gzip on&lt;/li&gt;
&lt;li&gt;Combine &amp;amp; minify js files&lt;/li&gt;
&lt;li&gt;Combine css files&lt;/li&gt;
&lt;li&gt;Optimize images, sprite the ones that make sense&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;The next round of changes are a bit more complex, but worth it:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Leverage browser caching, set far future expires, and have a strategy for updating the url (which you get for free with Rails)&lt;/li&gt;
&lt;li&gt;Either move the js files to the bottom, or use a 'deferred loading' strategy yui, lab.js, head.js, and others&lt;/li&gt;
&lt;li&gt;Remove unused code: find unused js and css and get rid of it&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;At this point I normally see a decent improvement in the rendering, the yslow/page speed scores improve, and things feel a little bit faster.&lt;/div&gt;&lt;div&gt;&amp;nbsp;Looking at a waterfall diagram, I should see less requests (particularly after they've been cached), much less data is downloaded, and the initial html download is a more significant percentage of the overall response time.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;From here I'd start profiling the backend:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Use a simple tool like apache bench or httperf to just hit the url and give me some baseline numbers (how many requests can the server handle at a time, and how long does a single response usually take)&lt;/li&gt;
&lt;li&gt;Analyze the logs to see which requests are most common, and which requests take the longest (we want to optimize the sweet spot of the most commonly used and slow requests), and confirm that all the numbers are making sense (my initial yslow times, the logs, and how it 'feel's when loading it).&lt;/li&gt;
&lt;li&gt;Then I'd pick a few of the requests and see where they spend their time&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;My approach is usually:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Run rack::bug, or other tools that will reveal the memory footprint, object creation, queries executed, and time spent in rendering.&lt;/li&gt;
&lt;li&gt;Try to narrow the slowness down to the main culprit, either using some debugging breakpoints, log statements, or the ruby benchmark utility.&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;At this point there tends to be a few main culprits:&lt;/div&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;&lt;ol&gt;&lt;li&gt;A single slow query&lt;/li&gt;
&lt;li&gt;Lots of object creation&lt;/li&gt;
&lt;li&gt;Lots of queries&lt;/li&gt;
&lt;li&gt;Cpu intensive work&lt;/li&gt;
&lt;li&gt;A long running call to a 3rd party (email, report generation, etc)&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;The majority of slow queries I encounter when doing performance assessments are actually pretty straight forward to fix. Its usually easy to see what data was expected, and figure out ways to rewrite the query to be faster and still get the right data back.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;A lot of poor performing queries are due to lack of indexes, or poorly defined indexes. (even today I fixed a query that was doing 'upper' on a column and was therefore not using the index. The query went from 4500ms to 1.6ms because it no longer needed to scan the whole table)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Beyond indexes, the next problem tends to be loading more data than is needed, followed by loading objects and traversing/filtering in code what could have been done much faster in the database.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;After cleaning up the low-hanging fruit, I start to look at more interesting issues:&lt;/div&gt;&lt;div&gt;..which I'll get into next time!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-2804662067353604633?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PiGiTa7p4vbZyXSkdlbCKZ9YY0o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PiGiTa7p4vbZyXSkdlbCKZ9YY0o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PiGiTa7p4vbZyXSkdlbCKZ9YY0o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PiGiTa7p4vbZyXSkdlbCKZ9YY0o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=ieCJDG_CoqA:Gk4zduAaNRs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=ieCJDG_CoqA:Gk4zduAaNRs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=ieCJDG_CoqA:Gk4zduAaNRs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=ieCJDG_CoqA:Gk4zduAaNRs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=ieCJDG_CoqA:Gk4zduAaNRs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/ieCJDG_CoqA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/2804662067353604633/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/12/performance-tuning-workflow.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/2804662067353604633?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/2804662067353604633?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/ieCJDG_CoqA/performance-tuning-workflow.html" title="Performance tuning workflow" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/12/performance-tuning-workflow.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8FSHY8eCp7ImA9WhZUEUw.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-3765159448966446213</id><published>2010-09-11T15:10:00.004-05:00</published><updated>2011-06-03T10:10:19.870-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-03T10:10:19.870-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="video" /><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="conference" /><category scheme="http://www.blogger.com/atom/ns#" term="windycityrails" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="newrelic" /><title>Rails Performance tuning Presentation from WindyCityRails Conference</title><content type="html">Slides&lt;br /&gt;
&lt;br /&gt;
&lt;div style="width:425px" id="__ss_5179720"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/johnny_zebra/windy-cityrails-performancetuning" title="Windy cityrails performance_tuning"&gt;Windy cityrails performance_tuning&lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse5179720" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=windycityrailsperformancetuning-100911093614-phpapp01&amp;stripped_title=windy-cityrails-performancetuning" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse5179720" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=windycityrailsperformancetuning-100911093614-phpapp01&amp;stripped_title=windy-cityrails-performancetuning" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="padding:5px 0 12px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/johnny_zebra"&gt;John McCaffrey&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
Here is the video from the conference&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;iframe src="http://player.vimeo.com/video/15067762?byline=0&amp;amp;portrait=0&amp;amp;color=b30000" width="600" height="450" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-3765159448966446213?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-EwrltfLqBs7ma32KamXjQ75TNQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-EwrltfLqBs7ma32KamXjQ75TNQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-EwrltfLqBs7ma32KamXjQ75TNQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-EwrltfLqBs7ma32KamXjQ75TNQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=FTvQ_zTkUBc:jIHoBf7aZO8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=FTvQ_zTkUBc:jIHoBf7aZO8:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=FTvQ_zTkUBc:jIHoBf7aZO8:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=FTvQ_zTkUBc:jIHoBf7aZO8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=FTvQ_zTkUBc:jIHoBf7aZO8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/FTvQ_zTkUBc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/3765159448966446213/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/09/rails-performance-tuning-presentation.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/3765159448966446213?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/3765159448966446213?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/FTvQ_zTkUBc/rails-performance-tuning-presentation.html" title="Rails Performance tuning Presentation from WindyCityRails Conference" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/09/rails-performance-tuning-presentation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MBQXw5fCp7ImA9Wx9RE0U.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-882725129874004116</id><published>2010-09-10T16:19:00.005-05:00</published><updated>2010-12-14T23:04:10.224-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-14T23:04:10.224-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="indexes" /><category scheme="http://www.blogger.com/atom/ns#" term="mysql" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><title>Mysql Performance analysis Improve performance by removing unused indexes from the database</title><content type="html">&lt;a href="http://1.bp.blogspot.com/_r7ptBSFSPbc/TQhLDUKPdeI/AAAAAAAANxM/69VYyaJfmQY/s1600/AquaDataStudio.jpeg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="164" src="http://1.bp.blogspot.com/_r7ptBSFSPbc/TQhLDUKPdeI/AAAAAAAANxM/69VYyaJfmQY/s200/AquaDataStudio.jpeg" width="200" /&gt;&lt;/a&gt;&lt;br /&gt;
After focusing on improving the initial page load of an application, the next most critical place to look is at the database, particularly checking the explain plan of the queries, and ensuring that the proper Database Indexes are in place. One thing that might not always show up is when you have indexes that aren't used. They certainly have a cost at insert, and they cause a lookup cost when the query planner is deciding which index to use, but it might not always be obvious.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A key component to how the query planner chooses the index is based on the 'selectivity' of the index. The selectivity is the ratio of distinct values against the total values of the column. The more unique values that are present, the more helpful it is to have an index. Which is also why you would probably not benefit from creating an index on a boolean, or similar elements with poor selectivity**.&lt;br /&gt;
&lt;br /&gt;
This reveals a key point about deciding what should be indexed:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Unique lookup values (foreign keys, ssn, phone, email)&lt;/li&gt;
&lt;li&gt;Join values&lt;/li&gt;
&lt;li&gt;Commonly searched values (** it would make sense to add an index on a boolean, in order for it to be picked up as a covering index)&lt;/li&gt;
&lt;/ol&gt;And what might not work out so well:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Columns with low selectivity&lt;/li&gt;
&lt;li&gt;Large data types&lt;/li&gt;
&lt;li&gt;Any columns on tables with only a few entries&lt;/li&gt;
&lt;/ol&gt;Here is a query I just tried out on my mysql db, to see what the selectivity of the indexes are:&lt;br /&gt;
&lt;script src="https://gist.github.com/574338.js"&gt;
 
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
The results are specific to the database you ran it against, and the distribution of data within it, so don't make any assumptions or extrapolations based on this data, its merely a way to quickly order and test the indexes that are available, against the data. In fact over at the &lt;a href="http://www.mysqlperformanceblog.com/2009/10/16/how-not-to-find-unused-indexes/"&gt;mysqlperformanceblog&lt;/a&gt;, they give a great example of when this technique would actually lead you astray.&lt;br /&gt;
&lt;br /&gt;
To really figure out which indexes should be removed, you have to see which ones are actually being used.&amp;nbsp; Which I'll have to cover in another post.&lt;br /&gt;
&lt;br /&gt;
I think I picked up this query from &lt;a href="http://www.scribd.com/doc/2376115/Coding-and-Indexing-Strategies-for-Optimal-Performance"&gt;these slides by Jay Pipes&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;div class="zemanta-pixie" style="height: 15px; margin-top: 10px;"&gt;&lt;img alt="" class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=099e6e1d-cd5e-4e07-94ea-ce9f54944100" style="border: medium none; float: right;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-882725129874004116?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ms3xuIdd9vbrFFN7UwNr13-N_Sk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ms3xuIdd9vbrFFN7UwNr13-N_Sk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ms3xuIdd9vbrFFN7UwNr13-N_Sk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ms3xuIdd9vbrFFN7UwNr13-N_Sk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=F2_CynMTgvo:uonOKYTTG_E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=F2_CynMTgvo:uonOKYTTG_E:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=F2_CynMTgvo:uonOKYTTG_E:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=F2_CynMTgvo:uonOKYTTG_E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=F2_CynMTgvo:uonOKYTTG_E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/F2_CynMTgvo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/882725129874004116/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/09/mysql-performance-analysis-improve.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/882725129874004116?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/882725129874004116?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/F2_CynMTgvo/mysql-performance-analysis-improve.html" title="Mysql Performance analysis Improve performance by removing unused indexes from the database" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_r7ptBSFSPbc/TQhLDUKPdeI/AAAAAAAANxM/69VYyaJfmQY/s72-c/AquaDataStudio.jpeg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/09/mysql-performance-analysis-improve.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UAR3w5eip7ImA9Wx5XEEQ.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-6276076154017901465</id><published>2010-09-09T23:56:00.002-05:00</published><updated>2010-09-10T00:07:26.222-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-10T00:07:26.222-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="railsconf" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="interview" /><category scheme="http://www.blogger.com/atom/ns#" term="remote" /><category scheme="http://www.blogger.com/atom/ns#" term="contract" /><category scheme="http://www.blogger.com/atom/ns#" term="wideteams" /><category scheme="http://www.blogger.com/atom/ns#" term="freelance" /><title>Ruby On Rails Development Interview: Freelance, Contract and Remote development</title><content type="html">I was &lt;a href="http://wideteams.com/interviews/146/"&gt;interviewed &lt;/a&gt;at RailsConf this year, by Avdi Grimm of WideTeams.org, regarding my experience with remote development, Agile Development, effective tools for remote collaboration, and how to be a successful freelance developer.&lt;br /&gt;
&lt;br /&gt;
After the interview I thought I was really rambling, but upon hearing it again, its not as bad as I thought.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://wideteams.com/interviews/146/"&gt;http://wideteams.com/interviews/146/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-6276076154017901465?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JRyzfk23UKXxlojy1GPdCabG_Ro/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JRyzfk23UKXxlojy1GPdCabG_Ro/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JRyzfk23UKXxlojy1GPdCabG_Ro/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JRyzfk23UKXxlojy1GPdCabG_Ro/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=Vq_m4U74O9I:g64Z_vI0ZvI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=Vq_m4U74O9I:g64Z_vI0ZvI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=Vq_m4U74O9I:g64Z_vI0ZvI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=Vq_m4U74O9I:g64Z_vI0ZvI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=Vq_m4U74O9I:g64Z_vI0ZvI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/Vq_m4U74O9I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/6276076154017901465/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/09/ruby-on-rails-development-interview.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/6276076154017901465?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/6276076154017901465?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/Vq_m4U74O9I/ruby-on-rails-development-interview.html" title="Ruby On Rails Development Interview: Freelance, Contract and Remote development" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/09/ruby-on-rails-development-interview.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UNRHo7fCp7ImA9Wx5RGUk.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-554742721904550119</id><published>2010-08-27T16:38:00.002-05:00</published><updated>2010-08-27T16:41:35.404-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-27T16:41:35.404-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="notes" /><category scheme="http://www.blogger.com/atom/ns#" term="vi" /><category scheme="http://www.blogger.com/atom/ns#" term="vim" /><title>vim notes</title><content type="html">I decided to just throw out a copy of all of the notes I have on Vim, some of these might not be right, as I'm still learning, but maybe you'll find something useful.&lt;br /&gt;
vim notes &lt;br /&gt;
&lt;div&gt;&lt;span style="font-family: 'times new roman';"&gt;&lt;b&gt;vi&lt;/b&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;basic use&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;[esc] is the escape key&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;vimtutor &amp;nbsp; &amp;nbsp;: starts vim editing a copy of a tutorial file -- very good.&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;i &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : insert mode &amp;nbsp;(so you can type)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;[esc] &amp;nbsp; &amp;nbsp; &amp;nbsp; : so you can navigate and edit commands (stop typing) (stop selecting)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;h j k l &amp;nbsp; &amp;nbsp; : move cursor (left, down, up, right)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;A &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : append at end of line (you can't navigate past the next to last character)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;u &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : undo last command&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;x &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : delete character under cursor&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;dd &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;: delete line (also puts it into the clipboard like buffer) &amp;nbsp;(d is delete)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;p &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : pastes what was in the buffer&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:wq &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : write and quit&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:w filename : Save a copy of the file you are editing as filename&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:q! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : quit without saving&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:help &amp;nbsp; &amp;nbsp; &amp;nbsp; : display help&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;[tab] &amp;nbsp; &amp;nbsp; &amp;nbsp; : use tab completion to check what your command is&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;COPY PASTE &amp;nbsp;(for CUT use d as described above)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;v &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : visual mode -- use to select text&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;y &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : use to yank (copy) what was selected above&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;l w e $ &amp;nbsp; &amp;nbsp; : these are special movements, letter, word, end of word, end of line&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;notes from going through the vimtutor tutorial (just type 'vimtutor' on the command line)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;A&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;to append&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;d(motion)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;dw &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;to delete word&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;d$ &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;to delete to the end of the line&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;d^&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;to delete to the beginng&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;motions work without a modifier, so just w, e $ and ^ jump around&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;dd to remove a line , but stores it in the register&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;2dd will remove 2 lines&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;u to undo the last command&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;ctrl-r will redo the last commands&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;use dd to delete a line, and p to paste it (put cursor above where you want it to go)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;r will let you replace the char under the cursor&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;c is for change (ce, cw, c$)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;ctrl-G to find out what line you are on&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&amp;nbsp;&amp;nbsp;or :set number&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;type the number then G to go to that line&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;there is a matching parenthesis search&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;ctrl-D to complete a command after typing :&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:help or F1 to get to help&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;ctrl-w ctrl-w to toggle windows&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;move your cursor to the topic: |quickref| and press ctrl-] to jump into it&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;ctrl-o to jump back&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:Explore to bring up the directory listing&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;enter to go down a dir&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;- or ctrl-o to go back&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;ctrl-o will also jump you back from a directory listing and out of a file&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;s in directory listing to sort by time, size, name&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;r will reverse the sort&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;i will bring in the time and size columns&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;Modes:&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;normal, insert and visual, there are others too&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;[esc] (C-[) takes you back to normal&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;Enter a number before a command to repeat it, examples:&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;10w &amp;nbsp; &amp;nbsp; &amp;nbsp;: skip forward 10 words&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;10dd &amp;nbsp; &amp;nbsp; : delete 10 lines&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;Useful tips&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:set ignorecase : you nearly always want this&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:syntax on &amp;nbsp; &amp;nbsp;: colour syntax in Perl,HTML,PHP etc&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;% &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : match brackets {}[]()&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;~ &amp;nbsp; &amp;nbsp; &amp;nbsp; : invert case (upper-&amp;gt;lower; lower-&amp;gt;upper) of current character&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;= &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : (re)indent the text on the current line or on the area selected&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;Substitution&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:%s/fred/joe/igc &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : general substitute command replace fred with joe, ignorecase&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:%s/\r//g &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;: delete DOS Carriage Returns (^M)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:s/\(.*\):\(.*\)/\2 : \1/ : reverse fields separated by : &amp;nbsp;notice the escape for \(&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:%s/^\(.*\)\n\1/\1$/ &amp;nbsp; &amp;nbsp; &amp;nbsp; : delete duplicate lines &amp;nbsp;(can vi sort stuff too?)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;global&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:g/^\s*$/d &amp;nbsp; &amp;nbsp; &amp;nbsp; : delete all blank lines&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:g!/^dd/d &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;: delete lines not containing string&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:v/^dd/d &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : delete lines not containing string&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:g/fred/,/joe/d &amp;nbsp;: not line based&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:v/./.,/./-1join : compress empty lines&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;matching&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;/fred\+/ : matches fred/freddy but not free. notice escaping the \+ (match 1 or more).&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;/codes\(\n\|\s\)*where : normal regexp with escaping&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;/\vcodes(\n|\s)*where &amp;nbsp;: \v for very magic, which cuts down on the escaping&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:292 to jump to line 292&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:set number &amp;nbsp;to turn line numbers on&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;Y to yank a line&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;yy&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;P to paste at cursor&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;p to paste below&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;2Y is 2 lines&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;y$ is to end of line&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;dd to delete a line&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;d3 to delete 3&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:set invlist to see the hidden characters&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:set ff to see the current os file type&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:set ff=unix to convert it to unix, dos, etc&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:set paste to paste without getting extra tabs (remember to set lf line endings if copying from windows)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:%s/\r/\r/g &amp;nbsp; To replace every CR with LF (when searching, \r matches CR, but when replacing, \r inserts LF):&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;:%s/\r$// To delete ^M only when it occurs at the end of a line:&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;to convert newlines in several files&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&amp;nbsp;&amp;nbsp; :args **\*&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&amp;nbsp;&amp;nbsp; maybe it should be **/* on windows&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&amp;nbsp;&amp;nbsp; :argdo se fileformat=dos|up&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;read more at &lt;a href="http://vim.wikia.com/wiki/"&gt;http://vim.wikia.com/wiki/&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: 'times new roman';"&gt;&lt;a href="http://aymanh.com/a-collection-of-vim-tips"&gt;http://aymanh.com/a-collection-of-vim-tips&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-554742721904550119?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/VUFJWdYBQZimFWRBTxIiXTrLlNs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VUFJWdYBQZimFWRBTxIiXTrLlNs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/VUFJWdYBQZimFWRBTxIiXTrLlNs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VUFJWdYBQZimFWRBTxIiXTrLlNs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=ReYqBv-XOqo:tg-aSoUp8_s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=ReYqBv-XOqo:tg-aSoUp8_s:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=ReYqBv-XOqo:tg-aSoUp8_s:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=ReYqBv-XOqo:tg-aSoUp8_s:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=ReYqBv-XOqo:tg-aSoUp8_s:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/ReYqBv-XOqo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/554742721904550119/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/08/vim-notes.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/554742721904550119?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/554742721904550119?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/ReYqBv-XOqo/vim-notes.html" title="vim notes" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/08/vim-notes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8GRH45fCp7ImA9Wx9RFE8.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-4437420125049694710</id><published>2010-08-27T13:44:00.005-05:00</published><updated>2010-12-15T09:43:45.024-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-15T09:43:45.024-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="lsrc" /><category scheme="http://www.blogger.com/atom/ns#" term="conference" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="photos" /><title>LoneStarRuby Conference notes and photos</title><content type="html">&lt;b&gt;General feel&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Great people&lt;/li&gt;
&lt;li&gt;Organizers are loose and let things just flow&lt;/li&gt;
&lt;li&gt;Sponsors are not interfering with the feel of the crowd&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Glenn VanderBurg&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Amazing presentation, should be required for any software student&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Jim Remsik and Robert Pitts: Vim&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;I really like these presenters, and even got a chance to spend some time with them during the conference. (In discussing their presentation, they both said they were not happy with how it turned out, and we kicked around ideas for how it could have gone better. My notes here are just a summary, not a criticism.)&lt;/li&gt;
&lt;li&gt;A late start changed the feel of the presentation, creating a bit of tension and a hurried feeling&lt;/li&gt;
&lt;li&gt;Good info, but I think a 'top 5 things you need to know about vim' summary might have helped&lt;/li&gt;
&lt;li&gt;I felt like the crowd may not have walked away with the basic knowledge the presenters were hoping for. (A good lesson for me about not trying to cram in too much stuff in a presentation, and be ready to roll with it if the schedule changes)&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;My additions&lt;/b&gt;&lt;/div&gt;&lt;div&gt;There is a lot of material to cover in a talk like this, and I personally really struggle with finding a good balance. It seems some of the best presentations are the ones that focus on just a few core concepts, get the audience excited, and then give them the resources to take the next step. Here are my thoughts on how to take someone at the very intro stage, and give them a place to get started.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;The &lt;a href="http://vimcasts.org/"&gt;VimCasts&lt;/a&gt; series is a great way to get an intro, as well as how to see specific problems solved in vim&lt;/li&gt;
&lt;li&gt;Type 'vimtutor' at the command line and go through the tutorial&lt;/li&gt;
&lt;li&gt;Use the interactive editor gem to expose vi to IRB (&lt;a href="http://vimcasts.org/episodes/running-vim-within-irb/"&gt;vimcast explaining the details&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://railsperformance.blogspot.com/2010/08/vim-notes.html"&gt;All my notes on Vim&lt;/a&gt;, as I've learned the basics&lt;/li&gt;
&lt;li&gt;Even if you aren't ready to go 'all in' with vi, the main point is to be efficient with the tools you use. Avoid taking your hands off the keyboard with any IDE, or tool. Learn to type without looking at your fingers, agree within your team on the tools that you will use together.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Gregg Pollack: Deciphering Yehuda&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Absolutely amazing presentation, anyone that cares about Rails3, and solid ruby development should watch this&lt;/li&gt;
&lt;li&gt;Anyone interested in how to put together a dense yet flowing technical presentation should watch this.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Pictures:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;embed flashvars="host=picasaweb.google.com&amp;amp;captions=1&amp;amp;hl=en_US&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Fjohn.mccaffrey%2Falbumid%2F5510159614994370129%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US" height="400" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="600"&gt;&lt;/embed&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-4437420125049694710?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/VsqxqzZ4Py6oyBQfvsYjrCbPVzk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VsqxqzZ4Py6oyBQfvsYjrCbPVzk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/VsqxqzZ4Py6oyBQfvsYjrCbPVzk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VsqxqzZ4Py6oyBQfvsYjrCbPVzk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=UCldzeHLSB4:IljFNNNNNgs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=UCldzeHLSB4:IljFNNNNNgs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=UCldzeHLSB4:IljFNNNNNgs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=UCldzeHLSB4:IljFNNNNNgs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=UCldzeHLSB4:IljFNNNNNgs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/UCldzeHLSB4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/4437420125049694710/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/08/lonestarruby-conference-notes-and.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/4437420125049694710?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/4437420125049694710?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/UCldzeHLSB4/lonestarruby-conference-notes-and.html" title="LoneStarRuby Conference notes and photos" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/08/lonestarruby-conference-notes-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYMRHs4eSp7ImA9Wx9RFE8.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-3480111501715333053</id><published>2010-07-21T13:01:00.002-05:00</published><updated>2010-12-15T09:49:45.531-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-15T09:49:45.531-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="chicago" /><category scheme="http://www.blogger.com/atom/ns#" term="speed tracer" /><category scheme="http://www.blogger.com/atom/ns#" term="windycityrails" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="page speed" /><category scheme="http://www.blogger.com/atom/ns#" term="yslow" /><category scheme="http://www.blogger.com/atom/ns#" term="chicagoruby" /><category scheme="http://www.blogger.com/atom/ns#" term="monitoring" /><category scheme="http://www.blogger.com/atom/ns#" term="presentation" /><title>Improving Rails Application Performance (ChicagoRuby Presentation)</title><content type="html">It was a good session at the suburban ChicagoRuby meetup on Saturday. The smaller crowd size allows for more discussion and exploring the areas that people are really interested in, instead of just sticking to the slides.&lt;br /&gt;
&lt;br /&gt;
I was glad to find out that most people were pretty familiar with &lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt;, but surprised that more people weren't aware of &lt;a href="http://developer.yahoo.com/yslow/"&gt;yslow&lt;/a&gt;, or &lt;a href="http://developer.yahoo.com/performance/rules.html"&gt;the performance tips its based on&lt;/a&gt;. (I didn't expect many people to know about Google &lt;a href="http://code.google.com/speed/page-speed/"&gt;Page Speed&lt;/a&gt;, or &lt;a href="http://code.google.com/webtoolkit/speedtracer/get-started.html"&gt;Speed tracer&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
We took some time to discuss particular issues, like how to decide where to spend your performance time, and a review of the workflow I use when doing an assessment. &amp;nbsp;(because we took the time to go over that, we then skipped over some of the tools)&lt;br /&gt;
&lt;br /&gt;
It was also announced that I will be presenting a session titled "Analyzing and Improving the Performance of your Rails Application" at this year's &lt;a href="http://windycityrails.org/sessions/#mccaffrey"&gt;WindyCityRails&lt;/a&gt; conference!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This makes the 3rd year that I've spoken at WindyCityRails (2008: 'Advanced Firebug, and javascript unit testing', 2009: '&lt;a href="http://prawn.heroku.com/"&gt;Rails PDF Generation&lt;/a&gt;')&lt;br /&gt;
&lt;br /&gt;
&lt;div id="__ss_4806794" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/johnny_zebra/improving-the-performance-of-rails-web-applications" title="improving the performance of Rails web Applications"&gt;improving the performance of Rails web Applications&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse4806794" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=performancemonitoringelm-100721113624-phpapp02&amp;stripped_title=improving-the-performance-of-rails-web-applications" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse4806794" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=performancemonitoringelm-100721113624-phpapp02&amp;stripped_title=improving-the-performance-of-rails-web-applications" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;div style="padding: 5px 0 12px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/johnny_zebra"&gt;John McCaffrey&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-3480111501715333053?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/sura0AXjasRrSua7EwDfriIQzwU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sura0AXjasRrSua7EwDfriIQzwU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/sura0AXjasRrSua7EwDfriIQzwU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sura0AXjasRrSua7EwDfriIQzwU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=LdBqiMNvA58:cQrKq0BIlro:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=LdBqiMNvA58:cQrKq0BIlro:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=LdBqiMNvA58:cQrKq0BIlro:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=LdBqiMNvA58:cQrKq0BIlro:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=LdBqiMNvA58:cQrKq0BIlro:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/LdBqiMNvA58" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/3480111501715333053/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/07/chicagoruby-presentation.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/3480111501715333053?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/3480111501715333053?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/LdBqiMNvA58/chicagoruby-presentation.html" title="Improving Rails Application Performance (ChicagoRuby Presentation)" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/07/chicagoruby-presentation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UAQXY8fCp7ImA9WxFUFEw.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-1122069508433679052</id><published>2010-06-24T17:36:00.002-05:00</published><updated>2010-06-24T17:40:40.874-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-24T17:40:40.874-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="indexes" /><category scheme="http://www.blogger.com/atom/ns#" term="mysql" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="postgres" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><title>tweaks to rails_indexes plugin to sort by table name and handle errors more gracefully</title><content type="html">One of the first things I do when working on a new project is to install the &lt;a href="http://github.com/eladmeidar/rails_indexes"&gt;rails_indexes&lt;/a&gt; plugin, and look for missing indexes. &amp;nbsp;Now I don't just take the plugin at its word and create the suggested migration, as it will tell you to add indexes on more stuff than you need (you don't need an index on your primary key as mysql and postgres will do that already), but I do look at the suggestions to learn about the model, where the joins are, and then see if there is an opportunity for improvement. I also use the &lt;a href="http://railsperformance.blogspot.com/2010/06/updates-to-railroad-application.html"&gt;railroad plugin&lt;/a&gt; to model the domain and see what I'm working with)&lt;br /&gt;
&lt;br /&gt;
Today I was using the Rails_indexes plugin on a large project and it blew up with some errors. It turns out there was a bug for how it handled non-model classes, which &lt;a href="http://github.com/eladmeidar/rails_indexes/network"&gt;a few people have patched&lt;/a&gt;, but they did it in some specific ways (like only detecting a controller) that I wasn't sure was going to work for me, so I just catch the error, log it and keep on truckin.&lt;br /&gt;
&lt;br /&gt;
The next issue I ran into was that the recommended migration file was huge for this project (tons of models, no indexes!), and it was hard to find what I was looking for, so I changed the code to sort the indexes by table name.&lt;br /&gt;
&lt;br /&gt;
If you haven't used the rails_indexes plugin on your project yet, you should. (I put it in a sep 'profiling' branch where I use all these tools to analyze the code, ensuring that the tools won't break anything)&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://github.com/jmccaffrey/rails_indexes"&gt;http://github.com/jmccaffrey/rails_indexes&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I still need to get the tests working in my local env, and add some coverage for my changes, and then issue a pull request, but for now this got me what I needed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-1122069508433679052?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aHhr8QtYhUETMhqKMXCYof7hozs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aHhr8QtYhUETMhqKMXCYof7hozs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aHhr8QtYhUETMhqKMXCYof7hozs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aHhr8QtYhUETMhqKMXCYof7hozs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=AinlhFl7o8s:C-bnMwoseR0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=AinlhFl7o8s:C-bnMwoseR0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=AinlhFl7o8s:C-bnMwoseR0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=AinlhFl7o8s:C-bnMwoseR0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=AinlhFl7o8s:C-bnMwoseR0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/AinlhFl7o8s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/1122069508433679052/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/06/tweaks-to-railsindexes-plugin-to-sort.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/1122069508433679052?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/1122069508433679052?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/AinlhFl7o8s/tweaks-to-railsindexes-plugin-to-sort.html" title="tweaks to rails_indexes plugin to sort by table name and handle errors more gracefully" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/06/tweaks-to-railsindexes-plugin-to-sort.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQNSX0_fip7ImA9WxFVF0Q.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-2553670578103048918</id><published>2010-06-17T10:57:00.001-05:00</published><updated>2010-06-17T10:59:58.346-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-17T10:59:58.346-05:00</app:edited><title>Updates to Railroad application modeling tool</title><content type="html">On Monday I started looking into a new project to help diagnose some performance problems in PDF report generation. When I size up a project, I use a varieties of tools and check lists to get my bearings (that might make a good post in itself), and one of the things I've added to my list is to generate a domain model graph, so I can see how the objects are related.&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;When it comes to performance, its always good to understand the structure of the data, and how its related. While you might find that just a few server tweaks can optimize performance, without forcing you to get tangled up in the code and potentially break something, at some point, you are going to need to understand the domain model, and how it is structured.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I've used the&amp;nbsp;&lt;a href="http://github.com/peterhoeg/RailRoad"&gt;http://github.com/peterhoeg/RailRoad&lt;/a&gt;&amp;nbsp;library in the past, and its always worked well. But when I got the current version and tried it out, I ran into a few problems.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;I couldn't ignore a pattern of files, only individual files&lt;/li&gt;
&lt;li&gt;It couldn't generate the graph for the controllers on a rails 2.3.5 project&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;I found a fork that solved the rails 2.3.5 problem, but not the exclusion problem. So I forked it and made the tests pass&amp;nbsp;&lt;a href="http://github.com/jmccaffrey/RailRoad"&gt;http://github.com/jmccaffrey/RailRoad&lt;/a&gt;, then went about adding some tests to prove the file glob pattern functionality I needed.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I run this command to get the graph for a basic Rails project:&lt;/div&gt;&lt;blockquote&gt;railroad -i -l -t -a -m -M | dot -Tsvg | sed 's/font-size:14.00/font-size:11.00/g' &amp;gt; doc/models_graph.svg&lt;/blockquote&gt;The sed part is to deal with an issue in Graphviz tools, which makes the command long, and I can never remember that, so I created an alias:&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;alias r_graph="railroad -i -l -t -a -m -M | dot -Tsvg | sed 's/font-size:14.00/font-size:11.00/g' &amp;gt; doc/models_graph.svg"&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
To exclude a pattern just add:&lt;br /&gt;
&lt;i&gt;-e app/models/specific_file.rb,app/models/*/*.rb&lt;/i&gt;&lt;br /&gt;
I didn't realize when playing with the patterns at first, that you don't need quotes, and there can't be any space between the commas. The second entry above will ignore any files in directories under the models dir.&lt;br /&gt;
&lt;br /&gt;
Here is an example from a simple project, using this command to generate a png&lt;br /&gt;
&lt;i&gt;railroad -i -l -t -a -m -M | dot -Tpng &amp;nbsp;&amp;gt; doc/models_graph.png&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_r7ptBSFSPbc/TBpFH4LMKYI/AAAAAAAAMxw/I-nYBSC-USE/s1600/models_graph.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/_r7ptBSFSPbc/TBpFH4LMKYI/AAAAAAAAMxw/I-nYBSC-USE/s320/models_graph.png" width="182" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I didn't try it on windows, or with any models that have acts_as_state_machine, though I did move things around, so its possible that I broke something. If you could pull it down, install it and tell me if you run into anything, I'll see if I can fix it. Its a cool tool, and I'd like to make it better if anyone has any ideas.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-2553670578103048918?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-6Vv3xy4CZKAr5qlGUUM7Yk6iiU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-6Vv3xy4CZKAr5qlGUUM7Yk6iiU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-6Vv3xy4CZKAr5qlGUUM7Yk6iiU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-6Vv3xy4CZKAr5qlGUUM7Yk6iiU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=SxIc0qu_7DY:b6mHtMp6vLE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=SxIc0qu_7DY:b6mHtMp6vLE:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=SxIc0qu_7DY:b6mHtMp6vLE:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=SxIc0qu_7DY:b6mHtMp6vLE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=SxIc0qu_7DY:b6mHtMp6vLE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/SxIc0qu_7DY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/2553670578103048918/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/06/updates-to-railroad-application.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/2553670578103048918?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/2553670578103048918?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/SxIc0qu_7DY/updates-to-railroad-application.html" title="Updates to Railroad application modeling tool" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_r7ptBSFSPbc/TBpFH4LMKYI/AAAAAAAAMxw/I-nYBSC-USE/s72-c/models_graph.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/06/updates-to-railroad-application.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIARXc7fyp7ImA9WxFVFEk.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-6672862519867046559</id><published>2010-06-13T10:04:00.007-05:00</published><updated>2010-06-13T10:55:44.907-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-13T10:55:44.907-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software development" /><category scheme="http://www.blogger.com/atom/ns#" term="Agile" /><category scheme="http://www.blogger.com/atom/ns#" term="clients" /><category scheme="http://www.blogger.com/atom/ns#" term="project" /><category scheme="http://www.blogger.com/atom/ns#" term="consulting" /><title>Mowing the grass: How to get out of the 'commodity software' game</title><content type="html">&lt;div style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;a href="http://www.flickr.com/photos/62468090@N00/140557217/" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank" title="After Mowing"&gt;&lt;img alt="After Mowing" border="0" src="http://farm1.static.flickr.com/51/140557217_3ebe991e53_m.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;small&gt;&lt;a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank" title="Attribution-ShareAlike License"&gt;&lt;img align="absmiddle" alt="Creative Commons License" border="0" height="16" src="http://www.pathf.com/blogs/wp-content/plugins/photo-dropper/images/cc.png" width="16" /&gt;&lt;/a&gt; &lt;a href="http://www.photodropper.com/photos/" target="_blank"&gt;photo&lt;/a&gt; credit: &lt;a href="http://www.flickr.com/photos/62468090@N00/140557217/" target="_blank" title="great_sea"&gt;great_sea&lt;/a&gt;&lt;/small&gt;&lt;/div&gt;A while ago &lt;a href="http://www.pathf.com/blogs/author/alice-toth/"&gt;Alice &lt;span class="goog-spellcheck-word" style="background: none repeat scroll 0% 0% yellow;"&gt;Toth&lt;/span&gt;&lt;/a&gt; and I had a conversation about how we can better serve our clients, and while we normally delve into project efficiencies like communication, developer training, and good &lt;span class="goog-spellcheck-word" style="background: none repeat scroll 0% 0% yellow;"&gt;QA&lt;/span&gt; practices, this time we both concluded that we need to do a better job of helping our clients reach their goals in the most efficient way possible, and sometimes that means 'talking them down' from the specific implementation idea they have, and finding a faster way to get there. &lt;br /&gt;
&lt;br /&gt;
I said that one of our challenges is that sometimes our clients feel they've hired us to just  'Mow the Grass', not discuss the landscape architecture, so we're not always in a place to be heard when it comes to discussing the fundamentals of a project.  &lt;a href="http://www.pathf.com/blogs/2009/05/just-mow-the-grass/"&gt;Alice wrote a nice post&lt;/a&gt; about what 'Just Mow the Grass' meant to her, and the strategy she's devised to find a nice middle ground.&lt;br /&gt;
&lt;br /&gt;
Here's how I see it:&lt;br /&gt;
&lt;br /&gt;
I was thinking about the times when we encounter projects that are looking for what I call 'commodity software development' which is to say they feel they already have all the requirements, and everything is all figured out, and they just need a fixed-bid project to have it built. The reality though is that most of the time the idea is not fully fleshed out, and needs a good deal of work. While there might be some giant spreadsheet of features, usually the core business goals aren't clear, and many fundamental issues have not been covered.&lt;br /&gt;
&lt;br /&gt;
If the customer thinks they have hired us to just 'mow the grass', they aren't in a place to hear any ideas about the big picture, they simply want us to 'build it', and at a consulting company you need projects, and you want to have happy customers, so it seems you can either just build exactly what they asked for, and hope it turns out for the best, or help them confirm the business fundamentals a bit, and verify that the plan will work.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;"I didn't hire you to question me"&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Its not easy to get into the fundamentals with customers, but the overall success of your work is dependent on knowing the fundamental assumptions that led to its creation, and in my mind that means we need to explore those ideas and test them out.&lt;br /&gt;
&lt;br /&gt;
The other comparison/metaphor I had been kicking around in my head goes like this:&lt;br /&gt;
&lt;br /&gt;
Imagine you are a building contractor. You build buildings to meet the needs of your clients, while adhering to the 'best practices' of your industry, (building codes, rules, regulations and prevalent design patterns). If a client comes to you and wants you to build a new 'asian-fusion' restaurant in an area that you are pretty sure its not going to take off, you could suggest that another location might work better, but in reality, the customer probably isn't interested in what a contractor has to say about the viability of a concept restaurant. If the concept doesn't take off, the contractor still got paid, the building is still standing and can be used for other purposes, and an outsider would not conclude that the restaurant failed because of anything related to the structure of the building itself. And while it might seem that the contractor doesn't care if the concept restaurant succeeds or not, let's suppose that if it had been successful it would lead to a long and profitable relationship where the contractor and the business owner continue to work together on new buildings and projects.&lt;br /&gt;
&lt;br /&gt;
So in this example, the 'building' project has specific and measurable requirements that are independent of the big picture success of the restaurant.&lt;br /&gt;
&lt;br /&gt;
Now comparing that to a software development project that is core to the business. The software product that is created is inextricably linked to the success of the big picture project, and the software is unlikely to stand on its own and be usable for some other business. In fact if the big picture project is not successful often times the software product itself is blamed.&lt;br /&gt;
&lt;br /&gt;
So its pretty clear to me that the success of a custom software project is built on knowing the foundation of the business goals, and that while following Agile Development practices will ensure that you are moving forward and getting work done, those tasks need to be tightly coupled to the business goals to ensure that you are getting the Right work done.&lt;br /&gt;
&lt;br /&gt;
I have seen many projects like this:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Client comes in with a big list of ideas "Guaranteed to change the market",&amp;nbsp; and a small/medium budget&lt;/li&gt;
&lt;li&gt;The ideas are turned into a feature list and timeline, the budget is expanded as each time the question "Do you really need that to launch?" is always answered with an unequivocal "Yes!!"&lt;/li&gt;
&lt;li&gt;Development begins, real-end user feedback is non-existent, and a single business expert is responsible for deciding how features should be done.&lt;/li&gt;
&lt;li&gt;At the midpoint of the original timeline, everyone on the team would say things are going well. The velocity is high, the product is taking shape, some major technical issues have been tackled, and things are moving forward at a good pace. Its not until things are getting ready for "Release" that it starts to fall apart. &lt;/li&gt;
&lt;li&gt;A beta/&lt;span class="goog-spellcheck-word" style="background: none repeat scroll 0% 0% yellow;"&gt;qa&lt;/span&gt; release is 'pushed back' as more 'must have' features get added, unknown stakeholders emerge with 'questions' and new must have requirements, "Killer" features are added as a way to justify where the previous time was spent, and the budget is rapidly disappearing.&lt;/li&gt;
&lt;li&gt;The Beta release finally happens, customers and stakeholders are underwhelmed, critical features are missing, the budget-eating "killer features" aren't resonating, a competitor goes to market with a simple but 'end-to-end' complete product, the team feels stressed and tensions are high.&lt;/li&gt;
&lt;li&gt;The budget is gone, the product is not complete and needs to be 'salvaged'. Accusations of 'over design', and 'over billing' begin. Team members are asked to 'review their timesheets', and make sure every last minute is documented.&lt;/li&gt;
&lt;li&gt;At this point the client either "doubles down", coming up with another round of funding to finish the project, or the thing dissolves into a legal battle, and general dissatisfaction on both sides.&lt;/li&gt;
&lt;/ol&gt;(I'm not saying this is how all projects go, and it certainly never happened on a project where I was the project manager, but I have been on some projects like this, and I have seen many play out this way)&lt;br /&gt;
&lt;br /&gt;
I've noticed this fundamental failure to align the proposed features of a product to their expected return more on iPhone projects, and other smaller budget projects. That's not to say that its not present on larger projects, just that its more noticeable on smaller projects.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="goog-spellcheck-word" style="background: none repeat scroll 0% 0% yellow;"&gt;Ok&lt;/span&gt;, so now what?&lt;br /&gt;
&lt;br /&gt;
Where as I had been suggesting that we need to just dive into the fundamentals of the project and balance out the features relative to their expected value, and that its our job to 'Fight' to make sure we're building the right solution to the right problem, Alice's suggestion was that we need to consistently deliver high-quality results on the tasks we've been charged to do, even if it is just 'Mowing the grass', in order to establish trust and credibility, and earn our place at the 'big table' of advice giving.&lt;br /&gt;
&lt;br /&gt;
What I don't like about Alice's idea is that its simple, elegant, logical, and its not mine!  (There's nothing worse than someone taking something you said and interpreting it to be more positive and cohesive than you realized)&lt;br /&gt;
&lt;br /&gt;
So with a balance of "just do what they asked", and "let's understand this business plan", we can make progress on the tasks that are laid out, moving forward, but also making sure we're moving in the right direction. &lt;br /&gt;
&lt;br /&gt;
Because everything seems just fine until you go to release and have real users touching the system, it seems pretty clear that the sooner you do that, the sooner you'll be able to correct course.&lt;br /&gt;
&lt;br /&gt;
You may have won this round Alice, but what will you do with customers like these?&lt;br /&gt;
&lt;br /&gt;
&lt;object width="640" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/R2a8TRSgzZY&amp;hl=en_US&amp;fs=1&amp;hd=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/R2a8TRSgzZY&amp;hl=en_US&amp;fs=1&amp;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-6672862519867046559?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mrgbJ3n7cftWD0a8CS2qwFsm36E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mrgbJ3n7cftWD0a8CS2qwFsm36E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mrgbJ3n7cftWD0a8CS2qwFsm36E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mrgbJ3n7cftWD0a8CS2qwFsm36E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=2IRxb-mDUXQ:uwGpUuo_BE8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=2IRxb-mDUXQ:uwGpUuo_BE8:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=2IRxb-mDUXQ:uwGpUuo_BE8:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=2IRxb-mDUXQ:uwGpUuo_BE8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=2IRxb-mDUXQ:uwGpUuo_BE8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/2IRxb-mDUXQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/6672862519867046559/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/06/mowing-grass-how-to-get-out-of.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/6672862519867046559?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/6672862519867046559?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/2IRxb-mDUXQ/mowing-grass-how-to-get-out-of.html" title="Mowing the grass: How to get out of the 'commodity software' game" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm1.static.flickr.com/51/140557217_3ebe991e53_t.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/06/mowing-grass-how-to-get-out-of.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEERnYyfSp7ImA9WxFVEUU.&quot;"><id>tag:blogger.com,1999:blog-5412562237506005821.post-2233214691140053401</id><published>2010-06-10T10:32:00.002-05:00</published><updated>2010-06-10T10:43:27.895-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-10T10:43:27.895-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="railsconf" /><category scheme="http://www.blogger.com/atom/ns#" term="musicjam" /><category scheme="http://www.blogger.com/atom/ns#" term="photos" /><title>RailsConf day #3 photos and videos</title><content type="html">Photos from the day &lt;a href="http://picasaweb.google.com/john.mccaffrey/RailsconfDay3"&gt;http://picasaweb.google.com/john.mccaffrey/RailsconfDay3&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;embed flashvars="host=picasaweb.google.com&amp;amp;captions=1&amp;amp;hl=en_US&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Fjohn.mccaffrey%2Falbumid%2F5480962193932706289%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US" height="267" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="400"&gt;&lt;/embed&gt;&lt;br /&gt;
&lt;br /&gt;
MusicJam photos &lt;a href="http://picasaweb.google.com/john.mccaffrey/RailsconfMusicjam"&gt;http://picasaweb.google.com/john.mccaffrey/RailsconfMusicjam&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;embed type="application/x-shockwave-flash" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" width="400" height="267" flashvars="host=picasaweb.google.com&amp;captions=1&amp;hl=en_US&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Fjohn.mccaffrey%2Falbumid%2F5481047059859805217%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;br /&gt;
&lt;br /&gt;
Videos&lt;br /&gt;
(you can see the full list, and full length video &lt;a href="http://www.justin.tv/johnny_zebra/videos"&gt;here on Justin.tv&lt;/a&gt;&lt;br /&gt;
Message in a bottle&lt;br /&gt;
&lt;br /&gt;
&lt;object type="application/x-shockwave-flash" height="300" width="400" id="clip_embed_player_flash" data="http://www.justin.tv/widgets/archive_embed_player.swf" bgcolor="#000000"&gt;&lt;param name="movie" value="http://www.justin.tv/widgets/archive_embed_player.swf" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowNetworking" value="all" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="flashvars" value="auto_play=false&amp;start_volume=25&amp;title=message in a bottle&amp;channel=johnny_zebra&amp;archive_id=265019049" /&gt;&lt;/object&gt;&lt;br /&gt;
&lt;a href="http://www.justin.tv/johnny_zebra#r=yfpDJnw~&amp;s=em" class="trk" style="padding:2px 0px 4px; display:block; width:320px; font-weight:normal; font-size:10px; text-decoration:underline; text-align:center;"&gt;Watch the Video on Justin.tv&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The Craziest 'CrazyTrain' I've ever seen&lt;br /&gt;
&lt;br /&gt;
&lt;object type="application/x-shockwave-flash" height="300" width="400" id="clip_embed_player_flash" data="http://www.justin.tv/widgets/archive_embed_player.swf" bgcolor="#000000"&gt;&lt;param name="movie" value="http://www.justin.tv/widgets/archive_embed_player.swf" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowNetworking" value="all" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="flashvars" value="auto_play=false&amp;start_volume=25&amp;title=This Crazy train is officially off the rails&amp;channel=johnny_zebra&amp;archive_id=265020220" /&gt;&lt;/object&gt;&lt;br /&gt;
&lt;a href="http://www.justin.tv/johnny_zebra#r=yfpDJnw~&amp;s=em" class="trk" style="padding:2px 0px 4px; display:block; width:320px; font-weight:normal; font-size:10px; text-decoration:underline; text-align:center;"&gt;Watch live video from johnny_zebra on Justin.tv&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Black Magic Woman&lt;br /&gt;
&lt;br /&gt;
&lt;object type="application/x-shockwave-flash" height="300" width="400" id="clip_embed_player_flash" data="http://www.justin.tv/widgets/archive_embed_player.swf" bgcolor="#000000"&gt;&lt;param name="movie" value="http://www.justin.tv/widgets/archive_embed_player.swf" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowNetworking" value="all" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="flashvars" value="auto_play=false&amp;start_volume=25&amp;title=black magic woman&amp;channel=johnny_zebra&amp;archive_id=265019173" /&gt;&lt;/object&gt;&lt;br /&gt;
&lt;a href="http://www.justin.tv/johnny_zebra#r=yfpDJnw~&amp;s=em" class="trk" style="padding:2px 0px 4px; display:block; width:320px; font-weight:normal; font-size:10px; text-decoration:underline; text-align:center;"&gt;Watch live video from johnny_zebra on Justin.tv&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Who&lt;br /&gt;
&lt;object type="application/x-shockwave-flash" height="300" width="400" id="clip_embed_player_flash" data="http://www.justin.tv/widgets/archive_embed_player.swf" bgcolor="#000000"&gt;&lt;param name="movie" value="http://www.justin.tv/widgets/archive_embed_player.swf" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowNetworking" value="all" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="flashvars" value="auto_play=false&amp;start_volume=25&amp;title=THe Who&amp;channel=johnny_zebra&amp;archive_id=265020395" /&gt;&lt;/object&gt;&lt;br /&gt;
&lt;a href="http://www.justin.tv/johnny_zebra#r=yfpDJnw~&amp;s=em" class="trk" style="padding:2px 0px 4px; display:block; width:320px; font-weight:normal; font-size:10px; text-decoration:underline; text-align:center;"&gt;Watch live video from johnny_zebra on Justin.tv&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
ZZ Top&lt;br /&gt;
&lt;br /&gt;
&lt;object type="application/x-shockwave-flash" height="300" width="400" id="clip_embed_player_flash" data="http://www.justin.tv/widgets/archive_embed_player.swf" bgcolor="#000000"&gt;&lt;param name="movie" value="http://www.justin.tv/widgets/archive_embed_player.swf" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowNetworking" value="all" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="flashvars" value="auto_play=false&amp;start_volume=25&amp;title=ZZ-Top&amp;channel=johnny_zebra&amp;archive_id=265020323" /&gt;&lt;/object&gt;&lt;br /&gt;
&lt;a href="http://www.justin.tv/johnny_zebra#r=yfpDJnw~&amp;s=em" class="trk" style="padding:2px 0px 4px; display:block; width:320px; font-weight:normal; font-size:10px; text-decoration:underline; text-align:center;"&gt;Watch live video from johnny_zebra on Justin.tv&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Blues Jam&lt;br /&gt;
&lt;object type="application/x-shockwave-flash" height="300" width="400" id="clip_embed_player_flash" data="http://www.justin.tv/widgets/archive_embed_player.swf" bgcolor="#000000"&gt;&lt;param name="movie" value="http://www.justin.tv/widgets/archive_embed_player.swf" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowNetworking" value="all" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="flashvars" value="auto_play=false&amp;start_volume=25&amp;title=ZZ-Top&amp;channel=johnny_zebra&amp;archive_id=265020323" /&gt;&lt;/object&gt;&lt;br /&gt;
&lt;a href="http://www.justin.tv/johnny_zebra#r=yfpDJnw~&amp;s=em" class="trk" style="padding:2px 0px 4px; display:block; width:320px; font-weight:normal; font-size:10px; text-decoration:underline; text-align:center;"&gt;Watch live video from johnny_zebra on Justin.tv&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5412562237506005821-2233214691140053401?l=www.railsperformance.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nxE-h6_LqorZCd29zlHC5IDwV3o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nxE-h6_LqorZCd29zlHC5IDwV3o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nxE-h6_LqorZCd29zlHC5IDwV3o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nxE-h6_LqorZCd29zlHC5IDwV3o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=3k8Uc7WIudc:bZ-FzUnPGsg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=3k8Uc7WIudc:bZ-FzUnPGsg:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=3k8Uc7WIudc:bZ-FzUnPGsg:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RailsPerformance?a=3k8Uc7WIudc:bZ-FzUnPGsg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RailsPerformance?i=3k8Uc7WIudc:bZ-FzUnPGsg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RailsPerformance/~4/3k8Uc7WIudc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.railsperformance.com/feeds/2233214691140053401/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.railsperformance.com/2010/06/railsconf-day-3-photos-and-videos.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/2233214691140053401?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5412562237506005821/posts/default/2233214691140053401?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RailsPerformance/~3/3k8Uc7WIudc/railsconf-day-3-photos-and-videos.html" title="RailsConf day #3 photos and videos" /><author><name>j_mccaffrey</name><uri>http://www.blogger.com/profile/08991073650849829788</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_r7ptBSFSPbc/TA2_MSpBRtI/AAAAAAAAMFg/d5t58OCxf0w/S220/marina_city_normal.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.railsperformance.com/2010/06/railsconf-day-3-photos-and-videos.html</feedburner:origLink></entry></feed>

