7 ms·
Speeding up a Rails request by 150ms by changing 1 line
- lallysingh 17y agoBetween the lot of these, the only message I'm getting is "ruby and rails authors happily dump speed in favor of not thinking terribly hard." Seriously, is it that hard to pull up dtrace and do a little analysis? They even have dtrace-ruby bindings on MacOS! http://www.infoq.com/news/2007/10/ruby-leopard http://www.infoq.com/news/2007/10/ruby-leopard
- icey 17y agoRails returns the body 1 line at a time? That can't seriously be true, can it?
- kscaldef 17y agoTrue. Seriously. At least in 2.3. Pre-Rack, I don't imagine that code would have been present.
- oldgregg 17y agoWhy the... ???
- icey 17y agoIs there a lot of per-line processing in Rails? Or is this something caused by Rack? I know next to nothing about Rails, so I'm sorry if these are questions with obvious answers. I just think the decision to process body responses on a per-line basis seems odd.
- kscaldef 17y agoIt's definitely odd. I'm inclined to attribute it to carelessness, and just not really thinking about the implications of precisely how they chose to implement the Rack specification. What's frustrating is that apparently there wasn't any performance testing of the 2.3 release that ought to have found this problem. It's been in the code base for about a year at this point.
- dasil003 17y agoHow often is ActionResponse.body a String? It's not really clear to me without digging deeper, but I could see this easily being an edge case related to certain caching and rendering methods. In any case, suggesting that any performance testing of Rails would have magically found this problem is unfair. Many many many Rails app instances are serving orders of magnitude more than 10reqs/sec, so clearly this is not a universal problem. My guess as to the reasoning here is so that large files can be served without blocking while the whole thing is written to the socket. Granted, that's just my gut instinct looking at that code, maybe it is just careless...
- EvilTrout 17y agoI've been running Rails 2.3 in production for a while with great performance. In the article the author mentions it has to do with serving static files, which is something that nobody should be using Rails to do anyway. I'm not surprised nobody found it until now.
- kscaldef 17y agoI checked that, and I couldn't find any case where the body _wasn't_ a String. It's true, that the problem only becomes really glaring when the pages being served are quite large (this example was 1300 lines of HTML), but I still assert that good performance regression testing ought to have popped this up. With 100 lines of output, which is pretty reasonable, you'd still be looking at an extra 10ms on each request.
- carbon8 17y agoIt's in 2.3 stable, but it appears to no longer be present in edge (in fact, ActionPack has already gone through a lot of changes): http://is.gd/xP8Y http://is.gd/xP8Y (github link)
- kscaldef 17y agoyeah, 3.0 changes a lot. It does appear that it will not exhibit the same problem.
- mtarnovan 17y agoString.each is the same as String.each_line in ruby 1.8. This code rewrite seems to be the reason that code breaks on ruby 1.9 if body is a string (this is guarded against in the body setter). (ruby 1.9 removes String.each) http://github.com/josh/rack/tree/master http://github.com/josh/rack/tree/master : * NOTE: String bodies break in 1.9, use an Array consisting of a single String instead. p.s. this is definitely worth a 2.3.3 tag and release
- jasonkester 17y agoIt makes me want to cry that people are still writing things in technologies that require you to drop little timing statements into your code to profile them. Profilers have been around for what? 30 years? I think the first time I hooked Ants Profiler up to an ASP.NET site was 2002. Are these other web technologies really that far behind the state of the art?
- mtarnovan 17y agoTake these kind of comments to Reddit, you obviously know nothing about Rails and Ruby, especially Rack and Metal. "Metal components operate outside the realm of the usual Rails timing and logging components, so you don’t get any internal measurements of page performance."
- jasonkester 17y agoIndeed, I'd never heard of Metal before reading this post. The quote you included is what lead me to wonder why there are not better tools for such a popular development framework as Ruby on Rails. As that quote states, there doesn't appear to be a profiler as such, but rather a set of "timing and logging components" built into the framework. If it's true, then ruby today is essentially handling profiling the same way PHP did it in 1998. I find that surprising and saddening.
- mtarnovan 17y agoSee above comment about dtrace probes, also there is ruby-perf and services like http://www.newrelic.com/features.html http://www.newrelic.com/features.html Also, what is the way PHP handles profiling in 2009 ? I haven't developed in php in quite a while, and I admit I never used anything more complicated then the profiling tools built in Zend Studio.
- kscaldef 17y agoI didn't feel like getting into the nitty-gritty details of my analysis, but Ruby does have a profiler, and it integrates into Rails quite well, and I was using it together with timers in this investigation. However, the exact same issue applies to the profiler as to simple timers, which is that the 150ms in question happens _after_ Rails hands off the reply to the web server, so as long as you are only measuring within the Rails framework, you will not see it.
- zcrar70 17y ago> We’re pretty obsessed with performance at Gilt Groupe Not wishing to troll, but I'm not sure that Ruby/Rails is you're looking for if you're obsessed with performance...
- callmeed 17y agoNot to put words in anyone's mouth, but perhaps he meant "obsessed with rails performance ..."
- ankhmoop 17y agoI'm not sure why individuals feel the need to write an entire page of text regarding a relatively straight-forward bug fixes. "Improved [Rails|Ruby|...] performance by [X] ms by changing [N < 20] lines of code" posts are becoming a common occurrence. The regular occurrence of such issues in a project implies an immature, poorly profiled code base, and are the kinds of things that other projects fix without fanfare. Our most recent database-backed dynamic web application can serve >10000 requests/sec on our mid-range hardware at <2 ms/req, which we achieved by running the most basic of profiling early on and throughout the development process, and using software that does the same. I don't expect a gold star for this.
- kscaldef 17y agoThe short and to-the-point version of the post went to the Rails-core mailing list. On my blog, I prefer to tell stories. Bragging about how fast you can serve a request is really meaningless when there's no way to know what's involved in that request. On my personal side projects (also using Rails), I serve requests in a couple milliseconds too. But, there's a vast, vast difference in what those sites do, vs what's involved in running a large-scale e-commerce operation.
- ankhmoop 17y agoThe short and to-the-point version of the post went to the Rails-core mailing list. On my blog, I prefer to tell stories. There are quite a few stories of this nature, which could simply be summarized as individuals finding incredibly simple inefficiencies and then fixing them.