Bruno Antunes
Bruno Antunes

Reputation: 2262

New to Rails, is this kind of performance normal?

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?

Upvotes: 1

Views: 433

Answers (7)

Andrew Rukin
Andrew Rukin

Reputation: 933

WEBrick is doing a reverse DNS lookup on connecting IPs by default. In other words, it's trying to see if your IP address is associated with a domain name. This is unnecessary and takes too long, so you can disable it.

Open the file "l/ruby/lib/ruby/1.9.1/webrick/config.rb" and locate the line with ":DoNotReverseLookup => nil". Change nil to true.

Enjoy!

Upvotes: 0

Simone Carletti
Simone Carletti

Reputation: 176352

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

Upvotes: 4

Zepplock
Zepplock

Reputation: 29135

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

Upvotes: 1

Terry
Terry

Reputation: 1088

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.

Upvotes: 4

Bob Martens
Bob Martens

Reputation: 13972

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

Upvotes: 4

Avdi
Avdi

Reputation: 18418

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.

Upvotes: 2

madlep
madlep

Reputation: 49656

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.

Upvotes: 3

Related Questions