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

<channel>
	<title>Merbist &#187; ruby</title>
	<atom:link href="http://merbist.com/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://merbist.com</link>
	<description>Random thoughts of a software developer</description>
	<lastBuildDate>Sat, 05 May 2012 14:16:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>MacRuby on iOS &#8211; RubyMotion review</title>
		<link>http://merbist.com/2012/05/04/macruby-on-ios-rubymotion-review/</link>
		<comments>http://merbist.com/2012/05/04/macruby-on-ios-rubymotion-review/#comments</comments>
		<pubDate>Fri, 04 May 2012 15:17:47 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[RubyMotion]]></category>

		<guid isPermaLink="false">http://merbist.com/?p=1363</guid>
		<description><![CDATA[Yesterday, RubyMotion was released and let&#8217;s be honest, it is one the best alternatives to Objective-C out there (if not the best). RubyMotion is a commercial, proprietary fork of MacRuby that targets iOS. This is not a small achievement, MacRuby relies on Objective C&#8217;s Garbage Collector (libauto) which is not available on iOS. Static compilation and [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, <a href="http://www.rubymotion.com/" target="_blank">RubyMotion</a> was released and let&#8217;s be honest, it is one the best alternatives to Objective-C out there (if not the best).</p>
<p>RubyMotion is a commercial, proprietary fork of MacRuby that targets iOS. This is not a small achievement, MacRuby relies on Objective C&#8217;s Garbage Collector (libauto) which is not available on iOS. Static compilation and new memory management solution was required to target the iOS platform . The new runtime had to be small and efficient. Furthermore, being able to run code on iOS isn&#8217;t enough, you need tools to interact with the compiler, to debug, to packages applications etc&#8230;</p>
<p>I don&#8217;t think anyone will contest the fact that RubyMotion is a well done product. The question however is, &#8220;<strong>is it worth for you to invest some money, time and energy in this product instead of using Apple&#8217;s language and tools</strong>&#8220;. In this article, I&#8217;ll try to balance the pros and cons of RubyMotion so you can have a better understanding of what RubyMotion could mean for you. As a disclaimer I should say that I was beta testing RubyMotion, that they are strong ties between RubyMotion and the MacRuby project I&#8217;m part of and finally that having MacRuby on iOS has been something I&#8217;ve been looking forward for a very long time.</p>
<p>Over the last few months I&#8217;ve seen RubyMotion take shape and finally hit the big 1.0. As you can see from <a href="http://twitter.com/#!/search/rubymotion?q=rubymotion" target="_blank">Twitter</a> and <a href="http://news.ycombinator.com/item?id=3924657" target="_blank">HackerNews</a>, the Ruby community is excited about being able to use their language to write statically compiled, native iOS apps. Spoiler alert, they are right, it&#8217;s a lot of fun.</p>
<p>&nbsp;</p>
<hr />
<p>&nbsp;</p>
<h2>What I like about RubyMotion:</h2>
<h3>Ruby Language</h3>
<p>I don&#8217;t mind Objective-C, I think it&#8217;s a fine superset of C, with the arrival of blocks, new literals and automatic memory management via ARC, Objective-C is actually getting better over time. But frankly, it&#8217;s not Ruby. You still have to deal with headers, you always have to compile your code via some weird Xcode voodoo settings, testing is a pain, the language, even with the new literals is quite verbose. On the other hand, using Ruby syntax I can get much more flexibility, reuse my code via mixins, easily reopen existing classes etc&#8230; At the end of the day, I end up with some code that seems cleaner, easier to understand and maintain even though I&#8217;m calling the same underlying APIs. Ruby&#8217;s flexibility also allows developers to make their own higher level APIs, take a look at some of the <a href="https://github.com/mattetti/BubbleWrap" target="_blank">wrappers/helpers</a> I wrote while playing with RubyMotion.</p>
<p style="text-align: center;"><a href="http://www.ruby-lang.org/en/"><img class="aligncenter  wp-image-1367" title="matt_aimonetti-Ruby_logo" src="http://merbist.com/wp-content/uploads/2012/05/matt_aimonetti-Ruby_logo-150x150.jpg" alt="Matt Aimonetti - Ruby Logo" width="90" height="90" /></a></p>
<h3>MacRuby</h3>
<p>RubyMotion is based on MacRuby, meaning that all the time and energy invested in the project will benefit RubyMotion&#8217;s users. All the concepts I explain in my <a href="http://shop.oreilly.com/product/0636920000723.do" target="_blank">MacRuby book</a> apply to RubyMotion. You don&#8217;t have to find workarounds to work with native APIs, Ruby objects are Objective-C objects and performance is great. I do regret Apple didn&#8217;t decide to embrace MacRuby for iOS but at the same time, even though we lost the Open Source aspect of the project and Apple&#8217;s backing, we gained much more flexibility and freedom on Laurent&#8217;s part.</p>
<p style="text-align: center;"><a href="https://www.amazon.com/dp/1449380379?tag=merbist-20&amp;camp=213381&amp;creative=390973&amp;linkCode=as4&amp;creativeASIN=1449380379&amp;adid=1SKHT7ABMG1YJZ3136WQ&amp;"><img class="aligncenter" title="MacRuby book" src="http://merbist.com/wp-content/uploads/matt_aimonetti/matt_aimonetti_macruby_book.gif" alt="" width="108" height="142" /></a></p>
<h3>REPL/Interactive shell</h3>
<p>RubyMotion doesn&#8217;t currently have a debugger, but it does have something Objective-C developers don&#8217;t have, a <a href="http://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop" target="_blank">REPL</a> working with the simulator. This feature is quite handy when debugging your application or learning the Cocoa APIs. You can click on a visual element in the simulator and start modifying the objects in real time in a terminal window and see the modifications in the simulator. It reminds me of the first time I used firebug to edit the html/css of a web page and saw the changes in real time.</p>
<p><a href="http://www.youtube.com/watch?feature=player_embedded&amp;v=rejYKzLglSE#!"><img class="aligncenter size-thumbnail wp-image-1368" title="matt aimonetti - RubyMotion REPL" src="http://merbist.com/wp-content/uploads/2012/05/matt_aimonetti-RubyMotion-REPL-150x150.jpg" alt="Matt Aimonetti - RubyMotion REPL" width="150" height="150" /></a></p>
<h3>Not dependent on Xcode</h3>
<p>Xcode is fine when you write Objective-C code, but it crashes often, it has a complicated UI and never really worked well for MacRuby due to the fact that Objective-C and Ruby have different requirements and the that Xcode is not open source. It&#8217;s also fully controlled by Apple and doesn&#8217;t provide APIs for 3rd party developers. (That said, the Xcode team has often helped out when a new released of Xcode broke MacRuby, so thank you guys).</p>
<p>Being able to use simple rake tasks to compile, simulate and deploy applications is just really really nice. I&#8217;m sure we&#8217;ll end up with better IDE integration, nice GUIs for some who like that, but in the meantime, as a &#8220;hacker&#8221;, I really enjoy the simplicity of the Rake tasks and not being forced in using a specific IDE.</p>
<p>&nbsp;</p>
<h3>Memory management</h3>
<p>Even though ARC made memory management much easier for Objective-C developers, when using RubyMotion you don&#8217;t have to worry about memory (well at least not explicitly, don&#8217;t be dumb and create a bazillion objects and hold references to them either). This includes the CoreFoundation objects that you still have to manually manage in Objective-C. Memory management is transparent and in most cases it&#8217;s really nice.</p>
<p>&nbsp;</p>
<hr />
<p>&nbsp;</p>
<h2>What I like less about RubyMotion</h2>
<p>Here is a list of things that are cons to using RubyMotion, note that while the list is longer than my list of &#8220;pros&#8221;, I listed a lot of small things. I also think that most of these issues will get solved in the next few months.</p>
<p>&nbsp;</p>
<h3>Ruby language</h3>
<p>There are some cases where Ruby just isn&#8217;t that great or is not an option. Examples include dealing with API relying heavily on pointers, when using some of the lower level APIs or when you have to interact with C++ (video game engines for instance). The good news is that within the same project, you can write part of your code in Objective-C and the rest in RubyMotion. The other thing that bothers me a little bit with writing Ruby code for iOS is that you can&#8217;t easily enforce argument types and therefore you are losing a lot of the features provided by Clang to the Objective-C developers. I dream of an optionally typed Ruby &#8212; but that&#8217;s a different topic.</p>
<p>Another downside of using Ruby is that Ruby developers will assume all standard libraries and gems will be compatible with RubyMotion. This isn&#8217;t the case. You need to think of RubyMotion as only offering the Ruby syntax (modulo a few differences). To be honest, most of the std libs and gems aren&#8217;t that useful when writing iOS apps. Even when I write MacRuby apps, I rarely rely on them and pick libraries designed to work in a non-blocking, multi-threaded environment (usually ObjC libs that I wrap).</p>
<p>&nbsp;</p>
<h3>Cocoa Touch</h3>
<p>If you&#8217;re already an iOS/OS X developer, you know that most of the hurdles aren&#8217;t the language syntax but the Cocoa APIs. These APIs are what you need to interact with to create your application. Cocoa APIs are usually much lower-level compared to what you usually see in Python, Ruby or even Java. While they are quite consistent, the APIs still have a stiff learning curve and currently,  if you want to write iOS applications, even if you know Ruby, you still have to learn Cocoa.</p>
<p>However, I do think that with RubyMotion now building a userbase, we will start seeing more and more <a href="https://github.com/mattetti/BubbleWrap" target="_blank">wrappers</a> around these sometimes <a href="https://github.com/HipByte/RubyMotionSamples/blob/master/GestureTable/app/gesture_recognizer.rb" target="_blank">hideous APIs</a>.</p>
<p>&nbsp;</p>
<h3>No Xcode/IDE</h3>
<p>There are cases where an IDE is really practical, especially when learning new APIs. Being able to have code completion, quick access to the documentation, instrumentation, debugging, interface builder, refactoring tools are things that Objective-C developers might have a hard time with when switching to RubyMotion. If you don&#8217;t know either Ruby or Cocoa, getting started with RubyMotion might be quite hard and you are probably not currently in the target audience.</p>
<p>&nbsp;</p>
<h3>Writing UI code by hand</h3>
<p>In some cases, it makes sense, in other, it should be much easier. I know that Laurent is working on a DSL to make that easier and I&#8217;m looking forward to it. But in the mean time, this is quite a painful exercise, especially due to the complexity of the Cocoa UI APIs. Using Xcode&#8217;s interface builder and Storyboards is something I know a lot of us wish we could do with RubyMotion when developing specific types of applications.</p>
<p><a href="http://kurrytran.blogspot.fr/2011/07/simple-ios-5-tutorial-using-storyboard.html"><img class="aligncenter size-full wp-image-1366" title="matt aimonetti storyboard" src="http://merbist.com/wp-content/uploads/2012/05/matt_aimonetti_storyboard-1.jpg" alt="Matt Aimonetti - Xcode iOS storyboard" width="600" height="384" /></a></p>
<h3>No debugger</h3>
<p>Again, this is eventually coming but the current lack of debugger can be problematic at times, especially when the problem isn&#8217;t obvious.</p>
<p>&nbsp;</p>
<h3>Lack of clear target audience</h3>
<p>It&#8217;s hard to blame a brand new product for not having clearly defined a target audience. But as a developer I find myself wondering &#8220;when should I use RubyMotion and for what kinds of problems?&#8221; Is RubyMotion great for quick prototypes I can then turn into production code? Or is good for throw away prototypes? Is it reserved for &#8220;fart and flash light&#8221; applications? Is it ready for prime time and should I invest and write my new awesome apps using it? Should I convert over my existing code base over from Titanium (or whatever other alternatives you used)? Should I use RubyMotion every time I would use Objective-C?</p>
<p>I guess we will see when the first applications start hitting the app store and people start reporting on their experience.</p>
<h3>Documentation</h3>
<p>I&#8217;m partially to blame here since I could have moved my butt and start writing a book but the point is nonetheless valid. All the iOS documentation out there is for Objective-C, all the APIs and samples provided by Apple are obviously only for Objective-C. Thankfully, you can use the 2 MacRuby books available out there to understand how to convert this existing documentation into something useful, but RubyMotion will need to provide better and more adapted documentation for beginners. I have no doubt that this is coming sooner than later.</p>
<p>&nbsp;</p>
<h3>Proprietary solution</h3>
<p>RubyMotion isn&#8217;t open source and currently fully relies on the shoulders of a single man. If unfortunately, Laurent goes out of business or decides to do something else then we will have to rewrite our apps in Objective-C.  Using RubyMotion for a professional product represents a significant business risk, which is exactly the same as using proprietary technology from any vendor. Apple could also decide to switch to JavaScript or rewrite iOS in Java and deprecate Objective-C. Let&#8217;s just say that it is unlikely.</p>
<p>I usually favor open source solutions, from the programming language I use to the OS I deploy on. This isn&#8217;t always possible and if you want to write iOS applications, you don&#8217;t currently have a choice. I do wish Laurent had found a way to make money while keeping the source code open. But who knows &#8212; after he makes his first million(s), he might change his mind.</p>
<p><a href="http://merbist.com/wp-content/uploads/2012/05/matt_aimonetti-rms.jpg"><img class="aligncenter size-thumbnail wp-image-1369" title="matt aimonetti - rms" src="http://merbist.com/wp-content/uploads/2012/05/matt_aimonetti-rms-150x150.jpg" alt="Matt Aimonetti - RMS" width="150" height="150" /></a></p>
<h2>Conclusion</h2>
<p>I would strongly suggest you consider giving RubyMotion a try. I can assure you that it will provide at least a few hours of &#8216;hacking fun&#8217; (and you will be able to brag about havng written your own iPhone app).  It will also help support financially someone who&#8217;s taking a risk in trying to push mobile development to the next level.</p>
<p>RubyMotion is, by far, my favorite alternative to Objective-C. But it is hard to tell, just 48 hours after its release, what people will do with it. Can it transcend the programming language barriers and attract Python, PHP, Java, ObjC and JavaScript developers? What is the sweet spot for RubyMotion applications? Will it affect the native vs web app battle? Can it make iOS development more accessible to the masses? Only time will tell.</p>
<p>What do you think?</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://merbist.com/2012/05/04/macruby-on-ios-rubymotion-review/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Introduction to mruby</title>
		<link>http://merbist.com/2012/04/27/introduction-to-mruby/</link>
		<comments>http://merbist.com/2012/04/27/introduction-to-mruby/#comments</comments>
		<pubDate>Fri, 27 Apr 2012 10:07:16 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[mruby]]></category>

		<guid isPermaLink="false">http://merbist.com/?p=1357</guid>
		<description><![CDATA[A couple days ago, I wrote an introduction article to help developers getting started with mruby (aka mrb). Besides explaining the difference between mrb and the other implementations, the article shows concrete examples to embed Ruby inside a C software application. The article doesn&#8217;t mention a few nice tricks such as mruby allowing you replace double [...]]]></description>
			<content:encoded><![CDATA[<p>A couple days ago, I wrote an introduction article to help developers <a title="how to mruby" href="http://matt.aimonetti.net/posts/2012/04/25/getting-started-with-mruby/" target="_blank">getting started with mruby</a> (aka mrb).</p>
<p><a href="matt.aimonetti.net/posts/2012/04/25/getting-started-with-mruby/"><img class="aligncenter size-full wp-image-1361" title="matt aimonetti - getting started with mruby" src="http://merbist.com/wp-content/uploads/2012/04/matt-aimonetti-getting-started-with-mruby.jpg" alt="matt aimonetti - getting started with mruby" width="860" height="687" /></a></p>
<p>Besides explaining the difference between mrb and the other implementations, the article shows concrete examples to embed Ruby inside a C software application. The article doesn&#8217;t mention a few nice tricks such as mruby allowing you replace <a title="mruby commit" href="https://github.com/mruby/mruby/commit/ee30c5a4a44fc26a8b5b8d6a0e35a7a4b6a6be50#diff-0" target="_blank">double by float</a> (though still imperfect), the possibility to replace the memory allocator and it was even reported to me that mruby can run on the <a href="http://en.wikipedia.org/wiki/Lego_Mindstorms" target="_blank">Lego Mindstorms</a> platform which only has 250K of memory!</p>
<p>mruby is still in alpha stage but it&#8217;s getting more interesting every day and at this rate it will soon become a real alternative to Lua.</p>
<p>Learn <a title="getting started with mruby" href="http://matt.aimonetti.net/posts/2012/04/25/getting-started-with-mruby/" target="_blank">how to get started with mruby</a> now.</p>
]]></content:encoded>
			<wfw:commentRss>http://merbist.com/2012/04/27/introduction-to-mruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>new Ruby: mruby and mobiruby Ruby for iOS/Android</title>
		<link>http://merbist.com/2012/04/23/new-ruby-mruby-and-mobiruby-for-ios-android/</link>
		<comments>http://merbist.com/2012/04/23/new-ruby-mruby-and-mobiruby-for-ios-android/#comments</comments>
		<pubDate>Mon, 23 Apr 2012 09:13:02 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://merbist.com/?p=1351</guid>
		<description><![CDATA[A few days ago, I wrote an article covering Ruby creator Matz&#8217; new Ruby implementation: mruby and its first related project: MobiRuby which aims to let Ruby developers write iOS and Android applications using their favorite language. &#160;]]></description>
			<content:encoded><![CDATA[<p>A few days ago, <a title="mruby and MobiRuby" href="http://matt.aimonetti.net/posts/2012/04/20/mruby-and-mobiruby/" target="_blank">I wrote an article</a> covering Ruby creator Matz&#8217; <a href="https://github.com/mruby/mruby" target="_blank">new Ruby implementation: mruby</a> and its first related project: <a href="http://mobiruby.org" target="_blank">MobiRuby</a> which aims to let Ruby developers write iOS and Android applications using their favorite language.</p>
<p>&nbsp;</p>
<p style="text-align: center;"><a href="http://matt.aimonetti.net/posts/2012/04/20/mruby-and-mobiruby/"><img class="aligncenter size-full wp-image-1352" title="Matt Aimonetti - mruby and MobiRuby" src="http://merbist.com/wp-content/uploads/2012/04/Matt-Aimonetti-mruby-and-MobiRuby.jpg" alt="Matt Aimonetti article on mruby and MobiRuby" width="600" height="412" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://merbist.com/2012/04/23/new-ruby-mruby-and-mobiruby-for-ios-android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learning from Rails&#8217; failures</title>
		<link>http://merbist.com/2012/02/29/learning-from-rails-failures/</link>
		<comments>http://merbist.com/2012/02/29/learning-from-rails-failures/#comments</comments>
		<pubDate>Wed, 29 Feb 2012 15:48:08 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://merbist.com/?p=1251</guid>
		<description><![CDATA[Ruby on Rails undisputedly changed the way web frameworks are designed. Rails became a reference when it comes to leveraging conventions, easy baked in feature set and a rich ecosystem. However, I think that Rails did and still does a lot of things pretty poorly.  By writing this post, I&#8217;m not trying to denigrate Rails, [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby on Rails undisputedly changed the way web frameworks are designed. Rails became a reference when it comes to leveraging conventions, easy baked in feature set and a rich ecosystem. However, I think that Rails did and still does a lot of things pretty poorly.  By writing this post, I&#8217;m not trying to denigrate Rails, there are many other people out there already doing that. My hope is that by listing what I think didn&#8217;t and still doesn&#8217;t go well, we can learn from our mistakes and improve existing solutions or create better new ones.</p>
<p><a href="http://merbist.com/2012/02/29/learning-from-rails-failures/train_fail/" rel="attachment wp-att-1253"><img class="aligncenter size-medium wp-image-1253" title="train fail" src="http://merbist.com/wp-content/uploads/2012/02/train_fail-300x188.jpg" alt="" width="300" height="188" /></a></p>
<h2>Migration/upgrades</h2>
<p>Migrating a Rails App from a version to the other is very much like playing the lottery, you are almost sure you will lose. To be more correct, you know things will break, you just don&#8217;t know what, when and how. The Rails team seems to think that everybody is always running on the cutting edge version and don&#8217;t consider people who prefer to stay a few version behind for stability reasons. What&#8217;s worse is that plugins/gems might or might not compatible with the version you are updating to, but you will only know that by trying yourself and letting others try and report potential issues.</p>
<p>This is for me, by far, the biggest issue with Rails and something that should have been fixed a long time ago. If you&#8217;re using the WordPress blog engine, you know how easy and safe it is to upgrade the engine or the plugins. Granted WordPress isn&#8217;t a web dev framework, but it gives you an idea of what kind of experience we should be striving for.</p>
<p>&nbsp;</p>
<h2>Stability vs playground zone</h2>
<p>New features are cool and they help make the platform more appealing to new comers. They also help shape the future of a framework. But from my perspective, that shouldn&#8217;t come to the cost of stability. Rails 3&#8242;s new asset pipeline is a good example of a half-baked solution shoved in a release at the last minute and creating a nightmare for a lot of us trying to upgrade. I know, I know, you can turn off the asset pipeline and it got better since it was first released. But shouldn&#8217;t that be the other way around? Shouldn&#8217;t fun new ideas risking the stability of an app or making migration harder, be off by default and turned on only by people wanting to experiment? When your framework is young, it&#8217;s normal that you move fast and sometimes break, but once it matures, these things shouldn&#8217;t happen.</p>
<p>&nbsp;</p>
<h2>Public/private/plugin APIs</h2>
<p>This is more of a recommendation than anything else. When you write a framework in a very dynamic language like Ruby, people will &#8220;monkey patch&#8221; your code to inject features. Sometimes it is due to software design challenges, sometimes it&#8217;s because people don&#8217;t know better. However,  by not explicitly specifying what APIs are private (they can change at anytime, don&#8217;t touch), what APIs are public (stable, will be slowly deprecated when they need to be changed) and which ones are for plugin devs only (APIs meant for instrumentation, extension etc..), you are making migration to newer versions much harder. You see, if you have a small, clean public API, then it&#8217;s easy to see what could break, warn developers and avoid migration nightmares. However, you need to start doing that early on in your project, otherwise you will end up like Rails where all code can potentially change anytime.</p>
<p>&nbsp;</p>
<h2>Rails/Merb merge was a mistake</h2>
<p>This is my personal opinion and well, feel free to disagree, nobody will ever be able to know to for sure. Without explaining what happened behind closed doors and the various personal motivations, looking at the end result, I agree with the group of people thinking that the merge didn&#8217;t turn up to be a good thing. For me, Rails 3 isn&#8217;t significantly better than Rails 2 and it took forever to be released. You still can&#8217;t really run a mini Rails stack like promised. I did hear that Strobe (company who was hiring Carl Lerche, Yehuda Katz and contracted Jose Valim) used to have an ActionPack based, mini stack but it was never released and apparently only Rails core members really knew what was going on there. Performance in vanilla Rails 3 are only now getting close to what you had with Rails 2 (and therefore far from the perf you were getting with Merb). Thread-safety is still OFF by default meaning that by default your app uses a giant lock only allowing a process to handle 1 request at a time. For me, the flexibility and performance focus of Merb were mainly lost in the merge with Rails. (Granted, some important things such as ActiveModel, cleaner internals and others have made their way into Rails 3)</p>
<p>But what&#8217;s worse than everything listed so far is that the lack of competition and the internal rewrites made Rails lose its headstart.  Rails is very much HTML/view focused, its primarily strength is to make server side views trivial and it does an amazing job at that. But let&#8217;s be honest, that&#8217;s not the future for web dev. The future is more and more logic pushed to run on the client side (in JS) and the server side being used as an API serving data for the view layer. I&#8217;m sorry but adding support for CoffeeScript doesn&#8217;t really do much to making Rails evolve ahead of what it currently is. Don&#8217;t get me wrong, I&#8217;m a big fan of CoffeeScript, that said I still find that Rails is far from being optimized to developer web APIs in Rails. You can certainly do it, but you are basically using a tool that wasn&#8217;t designed to write APIs and you pay the overhead for that. If there is one thing I wish Rails will get better at is to make writing pure web APIs better (thankfully there is Sinatra). But at the end of the day, I think that two projects with different philosophies and different approaches are really hard to merge, especially in the open source world. I wouldn&#8217;t go as far as saying like others that Rails lost its sexiness to node.js because of the wasted time, but I do think that things would have been better for all if that didn&#8217;t happen. However, I also have to admit that I&#8217;m not sure how much of a big deal that is. I prefer to leave the past behind, learn from my own mistake and move on.</p>
<p>&nbsp;</p>
<h2>Technical debts</h2>
<p>Here I&#8217;d like to stop to give a huge props to Aaron &#8220;<a href="http://twitter.com/tenderlove" target="_blank">@tenderlove</a>&#8221; Patterson, the man who&#8217;s actively working to reduce the <a href="http://en.wikipedia.org/wiki/Technical_debt" target="_blank">technical debts</a> in the Rails code base. This is a really hard job and definitely not a very glamorous one. He&#8217;s been working on various parts of Rails including its router and its ORM (ActiveRecord). Technical debts are unfortunately normal in most project, but sometimes they are overwhelming to the point that nobody dares touching the code base to clean it up. This is a hard problem, especially when projects move fast like Rails did. But looking back, I think that you want to start tackling technical debts on the side as you move on so you avoid getting to the point that you need a hero to come up and clean the piled errors made in the past. But don&#8217;t pause your entire project to clean things up otherwise you will lose market, momentum and excitement. I feel that this is also very much true for any legacy project you might pick up as a developer.</p>
<p>&nbsp;</p>
<h2>Keep the cost of entry level low</h2>
<p>Getting started with Rails used to be easier. This can obviously argued since it&#8217;s very subjective, but from my perspective I think we forgot where we come from and we involuntary expect new comers to come with unrealistic knowledge. Sure, Rails does much more than it used to do, but it&#8217;s also much harder to get started. I&#8217;m not going to argue how harder  it is now or why we got there. Let&#8217;s just keep in mind that it is a critical thing that should always be re-evaluated. Sure, it&#8217;s harder when you have an open source project, but it&#8217;s also up to the leadership to show that they care and to encourage and mentor volunteers to  focus on this important part of a project.</p>
<p>&nbsp;</p>
<h2>Documentation</h2>
<p>Rails documentation isn&#8217;t bad, but it&#8217;s far from being great. Documentation certainly isn&#8217;t one of the Ruby&#8217;s community strength, especially compared with the Python community, but what saddens me is to see the state of <a href="http://guides.rubyonrails.org/" target="_blank">the official documentation</a> which, should, in theory be the reference. Note that the Rails guides are usually well written and provide value, but they too often seem too light and not useful when you try to do something not totally basic (for instance use an ActiveModel compliant object). That&#8217;s probably why most people don&#8217;t refer to them or don&#8217;t spend too much time there. I&#8217;m not trying to blame anyone there. I think that the people who contributed theses guides did an amazing job, but if you want to build a strong and easy to access community, great documentation is key. Look at the <a title="Django docs" href="https://docs.djangoproject.com/en/1.3/" target="_blank">Django</a> documentation as a good example. That said, I also need to acknowledge the amazing job done by many community members such as <a href="http://railscasts.com/" target="_blank">Ryan Bates</a> and <a href="http://ruby.railstutorial.org/" target="_blank">Michael Hartl</a> consistently providing high value external documentation via the <a href="http://railscasts.com/" target="_blank">railscasts</a> and the intro to <a href="http://ruby.railstutorial.org/" target="_blank">Rails tutorial</a> available for free.</p>
<p>&nbsp;</p>
<p>In conclusion, I think that there is a lot to learn from Rails, lots of great things as well as lots of things you would want to avoid. We can certainly argue on Hacker News or via comments about whether or not I&#8217;m right about Rails failures, my point will still be that the mentioned issues should be avoided in any projects, Rails here is just an example. Many of these issues are currently being addressed by the Rails team but wouldn&#8217;t it be great if new projects learn from older ones and avoid making the same mistakes? So what other mistakes do you think I forgot to mention and that one should be very careful of avoiding?</p>
<p>&nbsp;</p>
<h3>Updates:</h3>
<ol>
<li>Rails 4 had an API centric app generator but it <a href="https://github.com/rails/rails/commit/6db930cb5bbff9ad824590b5844e04768de240b1">was quickly reverted</a> and will live as gem until it&#8217;s mature enough.</li>
<li>Rails 4 improved the ActiveModel API to be simpler to get started with. See <a href="http://blog.plataformatec.com.br/2012/03/barebone-models-to-use-with-actionpack-in-rails-4-0/">this blog</a> post for more info.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://merbist.com/2012/02/29/learning-from-rails-failures/feed/</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
		<item>
		<title>Quick dive into Ruby ORM object initialization</title>
		<link>http://merbist.com/2012/02/23/quick-dive-into-ruby-orm-object-initialization/</link>
		<comments>http://merbist.com/2012/02/23/quick-dive-into-ruby-orm-object-initialization/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 17:46:49 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[profiling]]></category>

		<guid isPermaLink="false">http://merbist.com/?p=1225</guid>
		<description><![CDATA[Yesterday I did some quick digging into how ORM objects are initialized and the performance cost associated to that. In other words, I wanted to see what&#8217;s going on when you initialize an ActiveRecord object. Before I show you the benchmark numbers and you jump to conclusions, it&#8217;s important to realize that in the grand [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I did some quick digging into how ORM objects are initialized and the performance cost associated to that. In other words, I wanted to see what&#8217;s going on when you initialize an ActiveRecord object.</p>
<p>Before I show you the benchmark numbers and you jump to conclusions, it&#8217;s important to realize that in the grand scheme of things, the performance cost we are talking is small enough that it is certainly not the main reason why your application is slow. Spoiler alert: ActiveRecord is slow but the cost of initialization isn&#8217;t by far the worse part of ActiveRecord. Also, even though this article doesn&#8217;t make activeRecord look good, and I&#8217;m not trying to diss it. It&#8217;s a decent ORM that does a great job in most cases.</p>
<p>Let&#8217;s get started by the benchmarks number to give us an idea of the damage (using Ruby 1.9.3 p125):</p>
<p>&nbsp;</p>
<pre>                                                             | Class | Hash  | AR 3.2.1 | AR no protection | Datamapper | Sequel |
--------------------------------------------------------------------------------------------------------------------------------------
.new() x100000                                               | 0.037 | 0.049 | 1.557    | 1.536            | 0.027      | 0.209  |
.new({:id=&gt;1, :title=&gt;"Foo", :text=&gt;"Bar"}) x100000          | 0.327 | 0.038 | 6.784    | 5.972            | 4.226      | 1.986  |</pre>
<p>&nbsp;</p>
<p>You can see that I am comparing the allocation of a Class instance, a Hash and some ORM models. The benchmark suite tests the allocation of an empty object and one with passed attributes. The benchmark in question is available <a title="object initialization benchmark" href="https://github.com/mattetti/benchmarks/blob/master/init_objects.rb" target="_blank">here</a>.</p>
<p>As you can see there seems to be a huge performance difference between allocating a basic class and an ORM class. Instantiating an ActiveRecord class is 20x slower than instantiating a normal class, while ActiveRecord offers some extra features, why is it so much slower, especially at initialization time?</p>
<p>The best way to figure it out is to profile the initialization. For that, I used <a href="https://github.com/tmm1/perftools.rb" target="_blank">perftools.rb</a> and I generated a graph of the call stack.</p>
<p>Here is what Ruby does (and spends its time) when you initialize a new Model instance (click to download the PDF version):</p>
<p>&nbsp;</p>
<p><a href="http://github.com/mattetti/benchmarks/blob/master/ar_init_profile.pdf?raw=true"><img class="aligncenter size-full wp-image-1329" title="AR model instantiation diagram by Matt Aimonetti" src="http://merbist.com/wp-content/uploads/2012/02/AR-model-instantation-by-Matt-Aimonetti.jpg" alt="Profiler diagram of AR model instantiation by Matt Aimonetti" width="600" height="395" /></a></p>
<p>&nbsp;</p>
<p>This is quite a scary graph but it shows nicely the features you are getting and their cost associated. For instance, the option of having the before and after initialization callback cost you 14% of your CPU time per instantiation, even though you probably almost never use these callbacks. I&#8217;m reading that by interpreting the node called ActiveSupport::Callback#run_callbacks, 3rd level from the top. So 14.1% of the CPU time is spent trying to run callbacks. As a quick note, note that 90.1% of the CPU time is spent initializing objects, the rest is spent in the loop and in the garbage collection (because the profiler runs many loops). You can then follow the code and see how the code works, creating a dynamic class callback method on the fly (the one with the long name) and then recreating the name of this callback to call it each time the object is allocated. It sounds like that&#8217;s a good place for some micro optimizations which could yield up to 14% performance increase in some cases.</p>
<p>Another major part of the CPU time is spent in ActiveModel&#8217;s sanitization. This is the piece of code that allows you to block some model attributes to be mass assigned. This is useful when you don&#8217;t want to sanitize your incoming params but want to create or update a model instance by using all the passed user params. To avoid malicious users to modify some specific params that might be in your model but not in your form, you can protect these attributes. A good example would be an admin flag on a User object. That said, if you manually initialize an instance, you don&#8217;t need this extra protection, that&#8217;s why in the benchmark above, I tested and without the protection. As you can see, it makes quite a big difference. The profiler graph of the same initialization without the mass assignment protection logically ends up looking quite different:</p>
<p>&nbsp;</p>
<p><a href="https://github.com/mattetti/benchmarks/blob/master/ar_init_no_protection.pdf?raw=true"><br />
</a><a href="https://github.com/mattetti/benchmarks/blob/master/ar_init_no_protection.pdf?raw=true"><img class="aligncenter size-full wp-image-1330" title="AR model instantiation without mass assignment - by Matt Aimonetti" src="http://merbist.com/wp-content/uploads/2012/02/AR-model-instantiation-without-mass-assignment-by-Matt-Aimonetti.jpg" alt="Matt Aimonetti shows the stack trace generated by the instantiation of an Active Record model" width="599" height="406" /></a></p>
<p>&nbsp;</p>
<p><strong>Update:</strong> My colleague <a title="Glenn's Twitter" href="https://twitter.com/#!/glv" target="_blank">Glenn Vanderburg</a> pointed out that some people might assuming that the shown code path is called for each record loaded from the database. This isn&#8217;t correct, the graph represents instances allocated by calling #new. See the addition at the bottom of the post for more details about what&#8217;s going on when you fetch data from the DB.</p>
<p>I then decided to look at the graphs for the two other popular Ruby ORMs:</p>
<p><a title="Datamapper" href="http://datamapper.org/" target="_blank">Datamapper</a></p>
<p><a href="https://github.com/mattetti/benchmarks/blob/master/dm_init_profile.pdf?raw=true"><img class="aligncenter" title="DataMapper object init Graph" src="http://img.skitch.com/20120223-txs4wa7b5rdpg45aj6354xg1wt.jpg" alt="" width="524" height="705" /></a></p>
<p>&nbsp;</p>
<p>and <a title="Sequel ORM" href="http://sequel.rubyforge.org/" target="_blank">Sequel</a></p>
<p style="text-align: center;"><a href="https://github.com/mattetti/benchmarks/blob/master/sequel_init_profile.pdf?raw=true"><img class="aligncenter" title="Sequel graph" src="http://img.skitch.com/20120223-p2jx6ypk35ucsgtx7p1tcabpes.jpg" alt="" width="531" height="656" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>While I didn&#8217;t give you much insight in ORM code, I hope that this post will motivate you to sometimes take a look under the cover and profile your code to see what&#8217;s going on and why it might be slow. <strong>Never assume, always measure</strong>. Tools such as perftools are a great way to get a visual feedback and get a better understanding of how the Ruby interpreter is handling your code.</p>
<h2>UPDATE:</h2>
<p>I heard you liked graphs so I added some more, here is what&#8217;s going on when you do Model.first:</p>
<p><a href="https://github.com/mattetti/benchmarks/blob/master/ar_first_profile.pdf?raw=true"><img class="aligncenter" title="ActiveRecord first" src="http://img.skitch.com/20120224-f23s8xctghi8mj6ax3cdw9aq25.jpg" alt="" width="539" height="884" /></a></p>
<p>&nbsp;</p>
<p>Model.all</p>
<p><a href="https://github.com/mattetti/benchmarks/blob/master/ar_all_profile.pdf?raw=true"><img class="aligncenter" title="Model.all profile graph" src="https://img.skitch.com/20120224-q29q4n7bj3i96erk1enxdqxb5e.jpg" alt="" width="834" height="884" /></a></p>
<p>&nbsp;</p>
<p>And finally this is the code graph for a call to Model.instantiate which is called after a record was retrieved from the database to convert into an Object. (You can see the #instantiate call referenced in the graph above).</p>
<p>&nbsp;</p>
<p><a href="https://github.com/mattetti/benchmarks/blob/master/ar_instantiate_profile.pdf?raw=true"><img class="aligncenter" title="Model.instantiate" src="http://img.skitch.com/20120224-8scmun9n1c9ufdnxa8rq2961bq.jpg" alt="" width="787" height="666" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://merbist.com/2012/02/23/quick-dive-into-ruby-orm-object-initialization/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>My RubyConf 2011 talk is online</title>
		<link>http://merbist.com/2011/12/09/my-rubyconf-2011-talk-is-online/</link>
		<comments>http://merbist.com/2011/12/09/my-rubyconf-2011-talk-is-online/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 14:47:59 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[garbage collector]]></category>
		<category><![CDATA[gil]]></category>

		<guid isPermaLink="false">http://merbist.com/?p=1203</guid>
		<description><![CDATA[I realize I forgot to mention that my RubyConf talk is now online on the confreaks site (wait until the end, Matz actually answers a question from the audience). I wrote a couple follow up posts you might also be interested in: About concurrency and the GIL Data safety and GIL removal]]></description>
			<content:encoded><![CDATA[<p>I realize I forgot to mention that my RubyConf talk is now online on the <a href="http://confreaks.net/videos/714-rubyconf2011-complex-ruby-concepts-dummified">confreaks site</a> (wait until the end, Matz actually answers a question from the audience).</p>
<p style="text-align: center;"><img class="aligncenter" src="http://mattetti.github.com/images/matt_aimonetti_presentation_ruby.jpg" alt="Photo of Matt Aimonetti giving a talk at RubyConf 2011 with one of his slides showing how thread scheduling works" width="653" height="422" /></p>
<p>I wrote a couple follow up posts you might also be interested in:</p>
<ul>
<li><a title="About concurrency and the GIL" href="http://merbist.com/2011/10/03/about-concurrency-and-the-gil/">About concurrency and the GIL</a></li>
<li><a title="Data safety and GIL removal" href="http://merbist.com/2011/10/18/data-safety-and-gil-removal/">Data safety and GIL removal</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://merbist.com/2011/12/09/my-rubyconf-2011-talk-is-online/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data safety and GIL removal</title>
		<link>http://merbist.com/2011/10/18/data-safety-and-gil-removal/</link>
		<comments>http://merbist.com/2011/10/18/data-safety-and-gil-removal/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 23:19:17 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[gil]]></category>
		<category><![CDATA[macruby]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://merbist.com/?p=1188</guid>
		<description><![CDATA[After my recent RubyConf talk and follow up post addressing the Ruby &#38; Python&#8217;s Global Interpreter Lock (aka GVL/Global VM Lock). a lot of people asked me to explain what I meant by &#8220;data safety&#8221;. While my point isn&#8217;t to defend one approach or the other, I spent a lot of time explaining why C [...]]]></description>
			<content:encoded><![CDATA[<p>After my recent <a title="RubyConf 2011 slides" href="http://rubyconf11.merbist.com" target="_blank">RubyConf talk</a> and <a title="About concurrency and the GIL" href="http://merbist.com/2011/10/03/about-concurrency-and-the-gil/" target="_blank">follow up post addressing the Ruby &amp; Python&#8217;s Global Interpreter Lock</a> (aka GVL/Global VM Lock). a lot of people asked me to explain what I meant by &#8220;data safety&#8221;. While my point isn&#8217;t to defend one approach or the other, I spent a lot of time explaining why C Ruby and C Python use a GIL and where it matters and where it matters less. As a reminder and as mentioned by Matz himself, the main reason why C Ruby still has a GIL is data safety. But if this point isn&#8217;t clear to you, you might be missing the main argument supporting the use of a GIL.</p>
<p>Showing obvious concrete examples of data corruption due to unsafe threaded code isn&#8217;t actually as easy at it sounds. First of all, even with a GIL, developers can write unsafe threaded code. So we need to focus only on the safety problems raised by removing the GIL. To demonstrate what I mean, I will try to create some race conditions and show you the unexpected results you might get. Again, before you go crazy on the comments, remember that threaded code is indeterministic and the code below might potentially work on your machine and that&#8217;s exactly why it is hard to demonstrate. Race conditions depend on many things, but in this case I will focus on race conditions affecting basic data structures since it might be the most surprising.</p>
<h2>Example:</h2>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">@<span style="color:#CC0066; font-weight:bold;">array</span>, threads = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#006666;">4</span>.<span style="color:#9900CC;">times</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  threads <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span>..<span style="color:#006666;">100</span>_000<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>n<span style="color:#006600; font-weight:bold;">|</span> @<span style="color:#CC0066; font-weight:bold;">array</span> <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; n<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
threads.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span> t.<span style="color:#9900CC;">join</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> @<span style="color:#CC0066; font-weight:bold;">array</span>.<span style="color:#9900CC;">size</span></pre></div></div>

<p>In the above example, I&#8217;m creating an instance variable of Array type and I start 4 threads. Each of these threads adds 100,000 items to the array. We then wait for all the threads to be done and check the size of the array.</p>
<p>If you run this code in C Ruby the end result will be as expected:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006666;">400000</span></pre></div></div>

<p>Now if you switch to JRuby you might be surprised by the output. If you are lucky you will see the following:</p>
<pre>ConcurrencyError: Detected invalid array contents due to unsynchronized modifications with concurrent users
        &lt;&lt; at org/jruby/RubyArray.java:1147
  __file__ at demo.rb:3
      each at org/jruby/RubyRange.java:407
  __file__ at demo.rb:3
      call at org/jruby/RubyProc.java:274
      call at org/jruby/RubyProc.java:233</pre>
<p>This is actually a good thing. JRuby detects that you are unsafely modifying an instance variable across threads and that data corruption will occur. However, the exception doesn&#8217;t always get raised and you will potentially see results such as:</p>
<pre>335467
342397
341080</pre>
<p>This is a sign that the data was corrupted but that JRuby didn&#8217;t catch the unsynchronized modification. On the other hand MacRuby and Rubinius 2 (dev) won&#8217;t raise any exceptions and will just corrupt the data, outputting something like:</p>
<pre>294278
285755
280704
279865</pre>
<p>In other words, if not manually synchronized, shared data can easily be corrupted. You might have two threads modifying the value of the same variable and one of the two threads will step on top of the other leaving you with a race condition. You only need 2 threads accessing the same instance variable at the same time to get a race condition. My example uses more threads and more mutations to make the problem more obvious. Note that TDD wouldn&#8217;t catch such an issue and even extensive testing will provide very little guarantee that your code is thread safe.</p>
<p>&nbsp;</p>
<h2>So what? Thread safety isn&#8217;t a new problem.</h2>
<p>That&#8217;s absolutely correct, ask any decent Java developer out there, he/she will tell how locks are used to &#8220;easily&#8221; synchronize objects to make your code thread safe. They might also mention the deadlocks and other issues related to that, but that&#8217;s a different story. One might also argue that when you write web apps, there is very little shared data and the chances of corrupting data across concurrent requests is very small since most of the data is kept in a shared data store outside of the process.</p>
<p>All these arguments are absolutely valid, the challenge is that you have a large community and a large amount of code out there that expects a certain behavior. And removing the GIL does change this behavior. It might not be a big deal for you because you know how to deal with thread safety, but it might be a big deal for others and C Ruby is by far the most used Ruby implementation. It&#8217;s basically like saying that automatic cars shouldn&#8217;t be made and sold, and everybody has to switch to stick shifts. They have better gas mileage, I personally enjoy driving then and they are cheaper to build. Removing the GIL is a bit like that. There is a cost associated with this decision and while this cost isn&#8217;t insane, the people in charge prefer to not pay it.</p>
<p>&nbsp;</p>
<h2>Screw that, I&#8217;ll switch to Node.js</h2>
<p>I heard a lot of people telling me they were looking into using Node.js because it has a better design and no GIL. While I like Node.js and if I were to implement a chat room or an app keeping connections for a long time, I would certainly compare it closely to EventMachine, I also think that this argument related to the GIL is absurd. First, you have other Ruby implementations which don&#8217;t have a GIL and are really stable (i.e: JRuby) but then Node basically works the same as Ruby with a GIL. Yes, Node is evented and single threaded but when you think about it, it behaves the same as Ruby 1.9 with its GIL. Many requests come in and they are handled one after the other and because IO requests are non-blocking, multiple requests can be processed concurrently but not in parallel. Well folks, that&#8217;s exactly how C Ruby works too, and unlike popular believe, most if not all the popular libraries making IO requests are non blocking (when using 1.9). So, next time you try to justify you wanting to toy with Node, please don&#8217;t use the GIL argument.</p>
<p>&nbsp;</p>
<h2>What should I do?</h2>
<p>As always, evaluate your needs and see what makes sense for your project. Start by making sure you are using Ruby 1.9 and your code makes good use of threading. Then look at your app and how it behaves, is it CPU-bound or IO-bound. Most web apps out there are IO-bound (waiting for the DB, redis or API calls), and when doing an IO call, Ruby&#8217;s GIL is released allowing another thread to do its work. In that case, not having a GIL in your Ruby implementation won&#8217;t help you. However, if your app is CPU-bound, then switching to JRuby or Rubinius might be beneficial. However, don&#8217;t assume anything until you proved it and remember that making such a change will more than likely require some architectural redesign, especially if using JRuby.  But, hey, it might totally be worth it as many proved it in the past.</p>
<p>&nbsp;</p>
<p>I hope I was able to clarify things a bit further. If you wish to dig further, I would highly recommend you read the many discussions the Python community had in the last few years.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://merbist.com/2011/10/18/data-safety-and-gil-removal/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>About concurrency and the GIL</title>
		<link>http://merbist.com/2011/10/03/about-concurrency-and-the-gil/</link>
		<comments>http://merbist.com/2011/10/03/about-concurrency-and-the-gil/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 05:23:54 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[fibers]]></category>
		<category><![CDATA[gil]]></category>
		<category><![CDATA[jruby]]></category>
		<category><![CDATA[macruby]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rubinius]]></category>
		<category><![CDATA[rubyconf]]></category>
		<category><![CDATA[threads]]></category>

		<guid isPermaLink="false">http://merbist.com/?p=1146</guid>
		<description><![CDATA[During RubyConf 2011, concurrency was a really hot topic. This is not a new issue, and the JRuby team has been talking about true concurrency for quite a while . The Global Interpreter Lock has also been in a subject a lot of discussions in the Python community and it&#8217;s not surprising that the Ruby [...]]]></description>
			<content:encoded><![CDATA[<p>During RubyConf 2011, concurrency was a really hot topic. This is not a new issue, and the JRuby team has been talking about true concurrency for quite a while . The Global Interpreter Lock has also been in a subject a<a href="http://wiki.python.org/moin/GlobalInterpreterLock" target="_blank"> lot of discussions in the Python community</a> and it&#8217;s not surprising that the Ruby community experiences the same debates since the evolution of their implementations are somewhat similar. (There might also be some tension between <a href="http://engineyard.com" target="_blank">EngineYard</a> hiring the JRuby and Rubinius teams and <a href="http://heroku.com" target="_blank">Heroku</a> which <a href="http://blog.heroku.com/archives/2011/7/12/matz_joins_heroku/" target="_blank">recently hired Matz</a> (Ruby&#8217;s creator) and <a href="https://github.com/nobu" target="_blank">Nobu</a>, the #1 C Ruby contributor)</p>
<p>The GIL was probably even more of a hot topic now that <a href="http://rubini.us/" target="_blank">Rubinius</a> is about the join <a href="http://jruby.org" target="_blank">JRuby</a> and <a href="http://macruby.org" target="_blank">MacRuby</a> in the realm of GIL-less Ruby implementations.</p>
<p>During my RubyConf talk (<a href="http://rubyconf11.merbist.com/">slides here</a>), I tried to explain how C Ruby works and why some decisions like having a GIL were made and why the Ruby core team isn&#8217;t planning on removing this GIL anytime soon. The GIL is something a lot of Rubyists love to hate, but a lot of people don&#8217;t seem to question why it&#8217;s here and why Matz doesn&#8217;t want to remove it. Defending the C Ruby decision isn&#8217;t quite easy for me since I spend my free time working on an alternative Ruby implementation which doesn&#8217;t use a GIL (MacRuby). However, I think it&#8217;s important that people understand why the MRI team (C Ruby team) and some Pythonistas feels so strongly about the GIL.</p>
<p><strong>What is the GIL?</strong></p>
<p>Here is a quote from the <a href="http://wiki.python.org/moin/GlobalInterpreterLock" target="_blank">Python wiki</a>:</p>
<blockquote><p>In CPython, the <strong>global interpreter lock</strong>, or <strong>GIL</strong>, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython&#8217;s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.) [...] The GIL is controversial because it prevents multithreaded CPython programs from taking full advantage of multiprocessor systems in certain situations. Note that potentially blocking or long-running operations, such as I/O, image processing, and <a href="http://wiki.python.org/moin/NumPy">NumPy</a> number crunching, happen <em>outside</em> the GIL. Therefore it is only in multithreaded programs that spend a lot of time inside the GIL, interpreting CPython bytecode, that the GIL becomes a bottleneck.</p></blockquote>
<p>The same basically applies to C Ruby. To illustrate the quote above, here is a diagram representing two threads being executed by C Ruby:</p>
<p style="text-align: center;"><a href="http://rubyconf11.merbist.com/#44"><img class="aligncenter" title="Ruby fair thread scheduling" src="http://rubyconf11.merbist.com/images/thread_scheduling.023.jpg" alt="Fair thread scheduling in Ruby by Matt Aimonetti" width="614" height="461" /></a></p>
<p>Such a scheduling isn&#8217;t a problem at all when you only have 1 cpu, since a cpu can only execute a piece of code at a time and context switching happens all the time to allow the machine to run multiple processes/threads in parallel. The problem is when you have more than 1 CPU because in that case, if you were to only run 1 Ruby process, then you would most of the time only use 1 cpu at a time. If you are running on a 8 cpu box, that&#8217;s not cool at all! A lot of people stop at this explanation and imagine that their server can only handle one request at a time and they they rush to sign Greenpeace petitions asking Matz to make Ruby greener by optimizing Ruby and saving CPU cycles. Well, the reality is slightly different, I&#8217;ll get back to that in a minute. Before I explain &#8220;ways to achieve true concurrency with CRuby, let me explain why C Ruby uses a GIL and why each implementation has to make an important choice and in this case both CPython and C Ruby chose to keep their GIL.</p>
<p>&nbsp;</p>
<h3>Why a GIL in the first place?</h3>
<ul>
<li>It makes developer&#8217;s lives easier (it&#8217;s harder to corrupt data)</li>
<li>It avoids race conditions within C extensions</li>
<li>It makes C extensions development easier (no write barriers..)</li>
<li>Most of the C libraries which are wrapped are not thread safe</li>
<li>Parts of Ruby&#8217;s implementation aren&#8217;t threadsafe (Hash for instance)</li>
</ul>
<div>As you can see the arguments can be organized in two main categories: data safety and C extensions/implementation. An implementation which doesn&#8217;t rely too much on C extensions (because they run a bit slow, or because code written in a different language is preferred) is only faced with one argument: data safety.</div>
<p>&nbsp;</p>
<h3></h3>
<h3>Should C Ruby remove its GIL?</h3>
<ul>
<li>No: it potentially makes Ruby code unsafe(r)</li>
<li>No: it would break existing C extensions</li>
<li>No: it would make writing C extensions harder</li>
<li>No: it&#8217;s a lot of work to change make C Ruby threadsafe</li>
<li>No: Ruby is fast enough in most cases</li>
<li>No: Memory optimization and GC is more important to tackle first</li>
<li>No: C Ruby code would run slower</li>
<li>Yes: we really need better/real concurrency</li>
<li>Yes: <a href="https://plus.google.com/107994348420168435683/posts/993U42yVbfk" target="_blank">Rubber boots analogy (Gustavo Niemeyer)</a></li>
</ul>
<div>Don&#8217;t count the amount of pros/cons to jump to the conclusion that removing the GIL is a bad idea. A lot of the arguments for removing the GIL are related. At the end of the day it boils down to data safety. During the Q&amp;A section of my RubyConf talk, Matz came up on stage and said data safety was the main reason why C Ruby still has a GIL. Again, this is a topic which was discussed at length in the Python community and I&#8217;d encourage you to read arguments from the <a href="http://www.jython.org/" target="_blank">Jython</a> (the equivalent of JRuby for Python) developers, <a href="http://codespeak.net/pypy/dist/pypy/doc/faq.html#does-pypy-have-a-gil-why" target="_blank">the PyPy</a> (the equivalent of Rubinius in the Python community) and CPython developers. (a good collection of arguments are actually available in the comments related to the <a href="https://plus.google.com/107994348420168435683/posts/993U42yVbfk" target="_blank">rubber boots post mentioned earlier</a>)</div>
<p>&nbsp;</p>
<h3>How can true concurrency be achieved using CRuby?</h3>
<div>
<ul>
<li>Run multiple processes (which you probably do if you use Thin, Unicorn or Passenger)</li>
<li>Use event-driven programming with a process per CPU</li>
<li>MultiVMs in a process. Koichi presented his plan to run multiple VMs within a process.  Each VM would have its own GIL and inter VM communication would be faster than inter process. This approach would solve most of the concurrency issues but at the cost of memory.</li>
</ul>
<div>Note:  forking a process only saves memory when using REE since it implements a GC patch that makes the forking process Copy on Write friendly. The Ruby core team worked on a patch for Ruby 1.9 to achieve the same result. <a href="http://twitter.com/#!/nari_en" target="_blank">Nari</a> &amp; <a href="http://twitter.com/#!/yukihiro_matz" target="_blank">Matz</a> are currently working on improving the implementation to make sure overall performance isn&#8217;t affected.</div>
</div>
<p>Finally, when developing web applications, each thread spend quite a lot of time in IOs which, as mentioned above won&#8217;t block the thread scheduler. So if you receive two quasi-concurrent requests you might not even be affected by the GIL as illustrated in <a href="http://yehudakatz.com/2010/08/14/threads-in-ruby-enough-already/" target="_blank">this diagram from Yehuda Katz</a>:</p>
<p><img class="aligncenter" title="rails threads" src="http://yehudakatz.com/wp-content/uploads/2010/08/Untitled.002.png" alt="" width="768" height="432" /></p>
<p>This is a simplified diagram but you can see that a good chunk of the request life cycle in a Ruby app doesn&#8217;t require the Ruby thread to be active (CPU Idle blocks) and therefore these 2 requests would be processed almost concurrently.</p>
<div>
<p>To boil it down to something simplified, when it comes to the GIL, an implementor has to chose between data safety and memory usage. But it is important to note that context switching between threads is faster than context switching between processes and data safety can and is often achieved in environments without a GIL, but it requires more knowledge and work on the developer side.</p>
<p>&nbsp;</p>
<h3>Conclusion</h3>
<div>The decision to keep or remove the GIL is a bit less simple that it is often described. I respect Matz&#8217; decision to keep the GIL even though, I would personally prefer to push the data safety responsibility to the developers. However, I do know that many Ruby developers would end up shooting themselves in the foot and I understand that Matz prefers to avoid that and work on other ways to achieve true concurrency without removing the GIL. What is great with our ecosystem is that we have some diversity, and if you think that a GIL less model is what you need, we have some great alternative implementations that will let you make this choice. I hope that this article will help some Ruby developers understand and appreciate C Ruby&#8217;s decision and what this decision means to them on a daily basis.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://merbist.com/2011/10/03/about-concurrency-and-the-gil/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Ruby optimization example and explanation</title>
		<link>http://merbist.com/2011/09/05/ruby-optimization-example-and-explaination/</link>
		<comments>http://merbist.com/2011/09/05/ruby-optimization-example-and-explaination/#comments</comments>
		<pubDate>Mon, 05 Sep 2011 22:58:21 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://merbist.com/?p=1124</guid>
		<description><![CDATA[Recently I wrote a small DSL that allows the user to define some code that then gets executed later on and in different contexts. Imagine something like Sinatra where each route action is defined in a block and then executed in context of an incoming request. The challenge is that blocks come with their context and [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I wrote a small DSL that allows the user to define some code that then gets executed later on and in different contexts. Imagine something like Sinatra where each route action is defined in a block and then executed in context of an incoming request.</p>
<p>The challenge is that blocks come with their context and you can&#8217;t execute a block in the context of another one.</p>
<p>Here is a reduction of the challenge I was trying to solve:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> SolutionZero
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>origin, <span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@origin</span> = origin
    <span style="color:#0066ff; font-weight:bold;">@block</span> = block
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> dispatch
    <span style="color:#0066ff; font-weight:bold;">@block</span>.<span style="color:#9900CC;">call</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
SolutionZero.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">42</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#0066ff; font-weight:bold;">@origin</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span> <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">dispatch</span>
<span style="color:#008000; font-style:italic;"># undefined method `+' for nil:NilClass (NoMethodError)</span></pre></div></div>

<p>The problem is that the block refers to the @origin instance variable which is not available in its context.<br />
My first workaround was to use instance_eval:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> SolutionOne
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>origin, <span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@origin</span> = origin
    <span style="color:#0066ff; font-weight:bold;">@block</span> = block
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> dispatch
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">instance_eval</span> <span style="color:#006600; font-weight:bold;">&amp;</span>@block
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
SolutionOne.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">40</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#0066ff; font-weight:bold;">@origin</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">dispatch</span>
<span style="color:#008000; font-style:italic;"># 42</span></pre></div></div>

<p>My workaround worked fine, since the block was evaluated in the context of the instance and therefore the @origin ivar is made available to block context. Technically, I was good to go, but I wasn&#8217;t really pleased with this solution. First using instance_eval often an indication that you are trying to take a shortcut. Then having to convert my block stored as a block back into a proc every single dispatch makes me sad. Finally, I think that this code is probably not performing as well as it could, mainly due to unnecessary object allocations and code evaluation.<br />
I did some benchmarks replacing <a title="instance_eval" href="https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1323" target="_blank">instance_eval</a> by <a title="instance_exec" href="https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1355" target="_blank">instance_exec</a> since looking at the C code, instance_exec should be slightly faster. Turns out, it is not so I probably missed something when reading the implementation code.</p>
<p>I wrote some more benchmarks and profiled a loop of 2 million dispatches (only the #disptach method call on the same object). The GC profiler report showed that the GC was invoked 287 times and each invocation was blocking the execution for about 0.15ms.<br />
Using Ruby&#8217;s <a href="http://ruby-doc.org/core/classes/ObjectSpace.html#M001526" target="_blank">ObjectSpace</a> and <a href="http://ruby-doc.org/core/classes/GC.html#M001373" target="_blank">disabling the GC</a> during the benchmark, I could see that each loop allocates an object of type T_NODE which is more than likely our @block ivar converted back into a block. This is quite a waste. Furthermore, having to evaluate our block in a different context every single call surely isn&#8217;t good for performance.</p>
<p>So instead of doing the work at run time, why not doing it at load time? By that I mean that we can optimize the #dispatch method if we could &#8220;precompile&#8221; the method body instead of &#8220;proxying&#8221; the dispatch to an instance_eval call. Here is the code:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> SolutionTwo
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>origin, <span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@origin</span> = origin
    implementation<span style="color:#006600; font-weight:bold;">&#40;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  private
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> implementation<span style="color:#006600; font-weight:bold;">&#40;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
    mod = <span style="color:#9966CC; font-weight:bold;">Module</span>.<span style="color:#9900CC;">new</span>
    mod.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:define_method</span>, <span style="color:#ff3333; font-weight:bold;">:dispatch</span>, block<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">extend</span> mod
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
SolutionTwo.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">40</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#0066ff; font-weight:bold;">@origin</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">dispatch</span>
<span style="color:#008000; font-style:italic;"># 42</span></pre></div></div>

<p>This optimization is based on the fact that the benchmark (and the real life usage) creates the instance once and then calls #dispatch many times. So by making the initialization of our instance a bit slower, we can drastically improve the performance of the method call. We also still need to execute our block in the right context. And finally, each instance might have a different way to dispatch since it is defined dynamically at initialization. To work around all these issues, we create a new module on which we define a new method called dispatch and the body of this method is the passed block. Then we simply our instance using our new module.</p>
<p>Now every time we call #dispatch, a real method is dispatched which is much faster than doing an eval and no objects are allocated. Running the profiler and the benchmarks script used earlier, we can confirm that the GC doesn&#8217;t run a single time and that the optimized code runs 2X faster!</p>
<p>&nbsp;</p>
<p>Once again, it&#8217;s yet another example showing that you <a href="http://merbist.com/2010/07/29/object-allocation-why-you-should-care/" target="_blank">should care about object allocation</a> when dealing with code in the critical path. It also shows how to work around the block bindings. Now, it doesn&#8217;t mean that you have to obsess about object allocation and performance, even if my last implementation is 2X faster than the previous, we are only talking about a few microseconds per dispatch. That said microseconds do add up and creating too many objects will slow down even your faster code since the GC will stop-the-world as its cleaning up your memory. In real life, you probably don&#8217;t have to worry too much about low level details like that, unless you are working on a framework or sharing your code with others. But at least you can learn and understand why one approach is faster than the other, it might not be useful to you right away, but if you take programming as a craft, it&#8217;s good to understand how things work under the hood so you can make educated decisions.<br />
&nbsp;</p>
<h3>Update:</h3>
<p>@apeiros in the comments suggested a solution that works &#038; performs the same as my solution, but is much cleaner:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> SolutionTwo
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>origin, <span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@origin</span> = origin
    define_singleton_method<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:dispatch</span>, block<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> block_given?
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://merbist.com/2011/09/05/ruby-optimization-example-and-explaination/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Discussion with a Java switcher</title>
		<link>http://merbist.com/2010/08/22/discussion-with-a-java-switcher/</link>
		<comments>http://merbist.com/2010/08/22/discussion-with-a-java-switcher/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 01:18:55 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://merbist.com/?p=796</guid>
		<description><![CDATA[discussion with an ex-java developer about why the Ruby community is not as he wish it was and why code is not focusing on what he thinks is important. ]]></description>
			<content:encoded><![CDATA[<p>For the past 6 months, I have had regular discussions with an experienced Java developers who switched to Ruby a couple years ago. Names have been changed to protect the guilty but to help you understand my friend &#8216;Duke&#8217; better, you need to know that he has been a developer for 10 years and lead many complicated, high traffic projects. He recently released two Ruby on Rails projects and he has been fighting with performance issues and scalability challenges.</p>
<p>Duke is a happy Ruby developer but he sometimes has a hard time understanding why things are done in a certain way in the Ruby community. Here are some extracts from our conversations. My answers are only based on my own experience and limited knowledge. They are probably not shared by the entire  community, feel free to use the comment section if you want to add more or share your own answers.</p>
<h2>Threads / Concurrency</h2>
<p><strong>Duke:</strong> Why does the Ruby community hate threads so much. It seems to be a taboo discussion and the only answer I hear is that threads are hard to deal with and that Ruby does not have a good threading implementation. What&#8217;s the deal there? If you want concurrent processing, threads are important!</p>
<p><strong>Me:</strong> This is a very good question and I think there are two main reasons why threads and thread safety are not hot topics in the Ruby world. First, look at Ruby&#8217;s main implementation itself. If you are using an old version of Ruby (pre Ruby 1.9) you don&#8217;t use native threads but green threads mapping to only 1 native thread. Ilya has a great (yet a bit old) <a href="http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/" target="_blank">blog post explaining the difference</a>, why it matters and also the role and effect of the Global Interpreter Lock (GIL). Also, even though Rubyists like to say that they live in the edge, most of them still use Ruby 1.8 and therefore don&#8217;t really see the improvements in Ruby 1.9 nor yet understand the potential of <a href="http://ruby-doc.org/core-1.9/classes/Fiber.html" target="_blank">fibers</a>.</p>
<p>The other part of the explanation is that the Rails community never really cared until recently. Yehuda Katz recently wrote a <a href="http://yehudakatz.com/2010/08/14/threads-in-ruby-enough-already/" target="_blank">good article on thread safety</a> in Ruby and if you read his post and <a href="http://dpaste.de/5xyG/raw/" target="_blank">Zed Shaw&#8217;s comment</a> you will understand a bit better the historical background. As a matter of fact, the current version of Rails is not multi-threaded by default and developers interested in handling concurrent requests in one process should <a href="http://api.rubyonrails.org/classes/Rails/Configuration.html#M002069" target="_blank">turn on this option</a>. Thread safety appeared for the first time in Rails 2.2 but from what I saw, most people still don&#8217;t enable this option. There are many reasons for that. First, enabling thread safety disables some Rails features like automatic dependency loading after boot and code reloading. A lot of Rails developers take these two features for granted and don&#8217;t understand that they are technically &#8220;hacks&#8221; to make their lives easier. I do believe a lot of Rails developers don&#8217;t understand how threads, thread safety, concurrency, blocking IO and dependencies work. They care about getting their app done and meet their deadlines. They usually use and know Rails without paying too much attention to how Rails extends Ruby. Imagine what would happen if their code wasn&#8217;t thread safe and Rails wasn&#8217;t not using a global lock by default. Now you see why things are not exactly as you expect and also why some Rubyists are getting excited about new projects like <a href="http://nodejs.org/" target="_blank">node.js</a> which takes a different approach.</p>
<p>The other thing to keep in mind is that at least 90 to 95% of the Rails apps out there don&#8217;t get more than a dozen requests/second (a million requests/day). You can scale that kind of load pretty easily using simple approaches like caching,  optimize your DB queries, load balancing to a couple servers. As a matter of fact, compared to the amount of people using Rails on a daily basis, only a very little amount of people are struggling with performance and scalability like you do. This is not an excuse but that explains why these people don&#8217;t care about the things you care about.</p>
<h2>Rails is slow</h2>
<p><strong>Duke:</strong> I don&#8217;t understand why Rails developers are not more concerned about the speed/performance penalty induced by Rails.</p>
<p><strong>Me:</strong> Again, Rails is fast enough for the large majority of developers out there. As you know, as a developer you have to always make compromises. The Rails team always said that development time is more expensive than servers and therefore the focus is on making development easier, faster and more enjoyable. However to get there, they have to somewhat sacrifice some performance. What can be totally unacceptable for you is totally fine for others and your contribution is always welcome. This is probably the root cause of the things you don&#8217;t like in Rails. Rails was built for startups, by startup developers and you don&#8217;t fall in this category. People contributing new features and fixes are the people using Rails for what it is designed to do. There is no real &#8216;Enterprise&#8217; support behind Rails and that might be why you feel the way you feel. Since you find yourself questioning some key Rails conventions and you are struggling with missing features, it looks  to me that you chose the wrong tool for the job since you don&#8217;t even use 70% of the Rails features and are dreaming of things such 3 tier architecture. <a href="http://sinatrarb.com" target="_blank">Sinatra</a> might be a better fit for you if you want lower level control, less conventions and less built-in features.</p>
<h2>Object allocation / Garbage Collection</h2>
<p><strong>Duke:</strong> I recently read that Twitter was spending <a href="http://blog.evanweaver.com/articles/2009/10/21/object-allocations-on-the-web/" target="_blank">20% of its request cycles in the GC</a>, am I the only finding that concerning?</p>
<p><strong>Me:</strong> Most people don&#8217;t realize how the GC works and what it means to allocate objects since Ruby does that automatically. But at the same time, most of these people don&#8217;t really see the affect of the Garbage Collection since they don&#8217;t have that much traffic or they scale in ways that just skips their Ruby stack entirely. (Or they just blame Ruby for being slow)</p>
<p>If you are app deals with mainly reads/GET requests, using HTTP caching (Rails has that built-in) and something like Varnish/<a href="http://rtomayko.github.com/rack-cache/" target="_blank">Rack-cache</a> will dramatically reduce the load on your server apps. Others don&#8217;t investigate their issues and just add more servers. As mentioned in a <a href="http://merbist.com/2010/07/29/object-allocation-why-you-should-care/" target="_blank">previous post</a>, some libraries like Builder are allocating LOTS more objects than others (Nokogiri), use the existing debugging tools to see where your object allocations occur and try to fix/workaround these. In other words, Ruby&#8217;s GC isn&#8217;t great but by ignoring its limitations, we made things even worse. My guess is that the GC is going to improve (other implementations already have better GCs) and that people will realize that Ruby is not magic and critical elements need to be improved.</p>
<h2>Tools</h2>
<p><strong>Duke:</strong> I really have a hard time finding good tools to help scale my apps better and understand where I should optimize my code.</p>
<p><strong>Me: </strong>It is true that we area lacking tools but things are changing. On top of the built-in tools like <a href="http://ruby-doc.org/core-1.9/classes/ObjectSpace.html" target="_blank">ObjectSpace</a>, <a href="http://ruby-doc.org/core-1.9/classes/GC/Profiler.html" target="_blank">GC::Profiler</a>, people interested in performance/debugging are working to provide the Ruby community with their expertise, look at <a href="http://memprof.com/" target="_blank">memprof</a> and <a href="http://rubyforge.org/projects/ruby-debug/" target="_blank">ruby-debug</a> for instance. Of course you can also use tools such as <a href="http://ruby-prof.rubyforge.org/" target="_blank">Ruby-prof</a>, <a href="http://kcachegrind.sourceforge.net/html/Home.html" target="_blank">Kcachegrind</a>, <a href="http://valgrind.org/" target="_blank">Valgrind</a> and <a href="http://www.gnu.org/software/gdb/" target="_blank">GDB</a>. (1.9.2 was <a href="http://github.com/yugui/ruby/tree/feature/dtrace" target="_blank">scheduled to have DTrace support</a> but I did not check yet). Maybe you should be more explicit about what tools you miss and how we could solve the gap.</p>
<h2>ActiveRecord</h2>
<p><strong>Duke:</strong> ActiveRecord doesn&#8217;t do what I need. How come there is no native support for master/slave DBs, sharding, DB view support is buggy,  suggested indexes on queries is not built-in and errors are not handled properly (server is gone, out of sync etc..)?</p>
<p><strong>Me:</strong> You don&#8217;t have to use ActiveRecord, you could use any ORM such as <a href="http://sequel.rubyforge.org/" target="_blank">Sequel</a>, <a href="http://datamapper.org/" target="_blank">DataMapper</a> or your own. But to answer your question, I think that AR doesn&#8217;t do everything you want because nobody contributed these features to the project and the people maintaining ActiveRecord don&#8217;t have the need for these features.</p>
<h2>What can we do?</h2>
<p>We, as a community, need to realize that we have to learn from other communities and other programming languages, this kind of humorous graph is unfortunately not too far from reality.</p>
<p style="text-align: center;"><img class="aligncenter" title="Programmer Hierarchy" src="http://i.imgur.com/G7WyP.gif" alt="" width="500" height="1105" /></p>
<p>Bringing your expertise and knowledge to the Ruby community is important. Looking further than just our own little will push us to improve and fulfill the gaps. Let the community know what tools you are missing, the good practices you think we should be following etc&#8230;</p>
<p>Take for instance <a href="http://nodejs.org/" target="_blank">Node.js</a>, it&#8217;s a port of <a href="http://wiki.github.com/eventmachine/eventmachine/" target="_blank">Ruby&#8217;s EventMachine</a> / <a href="http://twistedmatrix.com/trac/" target="_blank">Python&#8217;s twisted</a>. There is no reasons why the Ruby or Python versions could not do what the Javascript version does. However people are getting excited and are jumping ship. What do we do about that? One way would be to identify what makes node more attractive than EventMachine and what needs to be done so we can offer what people are looking for. I asked this question a few weeks ago and the response was that a lot of the Ruby libraries are blocking and having to check is too bothersome. Maybe that&#8217;s something that the community should be addressing. Node doesn&#8217;t have that many libraries and people will have to write them, in the mean time we can make our libs non-blocking. Also, let&#8217;s not forget that this is not a competition and people should choose the best tool for their projects.</p>
<p>Finally, things don&#8217;t change overnight, as more people encounter the issues you are facing, as we learn from others, part of the community will focus on the problems you are seeing and things will get better. Hopefully, <strong>you</strong> will also be able to contribute and influence the community to build an even better Ruby world.</p>
]]></content:encoded>
			<wfw:commentRss>http://merbist.com/2010/08/22/discussion-with-a-java-switcher/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>

