views:

243

answers:

6

I have an app and in it's only controller, an action is thus configured:

def do_call
    response = <<EOF
<real-time-stat>
<awt type="integer">1</awt>
<cc type="integer">5</cc>
<cp type="integer">0</cp>
<dc type="integer">0</dc>
<ef type="float">100.0</ef>
<rc type="integer">6</rc>
<sl type="float">100.0</sl>
<state type="integer">0</state>
<ts type="datetime">2009-07-24T10:36:57Z</ts>
<wc type="integer">0</wc>
<wprc type="float">0.0</wprc>
<real-time-stat>
EOF
    respond_to do |format|
      format.xml { render :xml => response }
    end
  end

This is a test for an action that will, in the future, retrieve the fields from a MySQL DB. However, running this code in production mode, from a LOCAL WEBrick server on port 3000 running on a Pentium 4 (kinda old, but dual core) machine, I'm getting response times (measured by YSlow, a Yahoo! add-on for Firebug) of 175 to 500 milliseconds (wildly fluctuating)!

It this normal? Am I doing it wrong? Considering I wish to aggregate several queries in a single response and XML-ify all of them (to use with ActiveResource), I'm getting bells going off saying it can't possibly scale... :|

Thanks for any feedback!

EDIT: changing to Mongrel does not change the situation much, still 175-300 ms per response. However, the logs show 0 to 15 ms per "completed" request (200 OK). Is the difference all attributable to Firefox's rendering of the XML? If not, where can it come from?

+2  A: 

Only thing I can think of is to use a different webserver. webrick is very slow.

Using Mongrel or Thin would give you better performance.

Also, even though you are in production mode, just double check the production.rb configuration settings, and make sure class caching etc is turned on still.

madlep
+1  A: 

Off-the-cuff response: don't use WebRick. It's slow. Really slow. Install mongrel and Rails will use it automatically. In production, use mongrel or Passenger.

Avdi
+3  A: 

Webrick is slow. Try running it again under a nice Passenger setup and then report back.

Bob Martens
+2  A: 

There are several implications that causes your test to be not too much representative. Let me explain a few:

  1. You are running test in a development environment. The development environmnt (defined in config/environments/development.rb) is largely different than the production one (defined in config/environments/development.rb). First it doesn't cache your classes so the most part of your application libraries is reloaded at any request. On production, Rails caches your objects on boot and doesn't parse the code base again. This is a super-performance boost.

  2. As you have been told, you are using the worst web server available to run. You should use Mongrel or, to run a real benchmark, you should use the same server that you are going to use in production.

  3. It's often a good rule to run tests on an environment equal or similar to the final one. Running a test in development mode and trying to guess how it will perform online doesn't provide you any good information at all.

  4. You are missing cache. Rails provides many different caching level. To improve your performance you might consider to cache your model requests and/or your responses with page/action/fragment caching. Also, you might want to take advantage of HTTP headers sending 304 http headers when the content is not modified and setup a reverse proxy.

  5. For this specific case of response, you might want to skip the full Rails action/controller stack and implement a Rails::Metal layer so that your response will be served as soon as it's ready

Simone Carletti
First off, I'm NOT saying Rails doesn't perform - I'm asking if this is normal. There's a big difference. And second, I'm running this in production, as shown by the *BOLD* text in my original question. Perhaps you should read the question more carefully before dismissing it as "absolutely pointless".
sardaukar
I'm sorry sardaukar, I miss the piece where you told about the environment. Anyway, all the other points can still influence the test.
Simone Carletti
I suppose you must see this kind of question/flamebait all the time. Still, I was just asking to see if I was doing it wrong.
sardaukar
+4  A: 

If you're just running a webserver locally and hitting it with Firefox to measure performance, you're going to get erratic, misleading, and questionable results.

Try turning off everything but your webserver, and use either ab or HTTPerf to get a more reliable metric for performance.

If you still see poor response times for only spitting back a string, a good tool is RubyProf, which you can run and see where Rails is spending time.

Terry
thanks for the tool pointers!
sardaukar
thanks for the accept! :)
Terry
+1  A: 

wrap your call in

  start = Time.now
  ...
  elapsed_time = Time.now - start

and see how many seconds it takes.

Other tests will be unreliable on your dev platform until you deploy it to productions server

Zepplock
thanks, was already doing it in some parts of the code!
sardaukar