Even after you kick out an app, you’ve got to stop and think about how fast it is. I’m doing this a bit late, considering that my online dictionary Ninjawords is in its second release, but hey, better late than never.
I’m a bit worried about the requests per second for Ninjawords. It has a pretty large database of 200k words, each having 1-5 definitions, and each definition having 1-3 examples. Rails Activerecord fetches each object (word, then its definitions, and then the definitions’ examples) from the database in a separate query, so any one lookup can trigger ~20 queries. Even though each query is fast, that many queries can take you from response times of 0.02ms (50req/s) to 0.2ms (5req/s) pretty quickly.
The first order of business is always to make sure your tables are indexed (which can be done via add_index in Activerecord migrations).
In searching for other methods to speed up Ninjawords, I stumbled upon Stefan Kaes’s excellent Rails performance blog. Worth reading the entire thing, but Stefan has written a great plugin to achieve piggy-backed attributes on your queries. If you fetch a lot of other objects through one object’s assocations (word->definitions->examples), then piggy backing can reduce the number of total queries made to the database, using joins to get all the data in one go.
Helped my application, but my numbers are still low. Ninjawords can pull a word from the db and render it at anywhere from 50req/s to 3req/s (I have no idea why the variance is so high). I don’t get that much traffic to care, except that I’d like to make Ninjawords accessible via an api, and for that it will need more speed.
I wonder what a “normal” req/s number is for a Rails app running on a 500mhz webserver…
I’ll post more if I make any significant discoveries. I think I’m going to do pruning and preprocessing on the database itself, so it doesn’t have to be done on each request. I don’t display all of the data I have (I only display 3 definitions per article, when there could possibly be 20), so I can cut what I don’t display instead of querying for it all and then filtering it out on the view. I’ll also replace links in the definitions, which requires running regular expressions over each piece of text. I can do that all at once when I construct the database from its source files (Wiktionary). Not as flexible, but Ninjaword’s view is not likely to change anytime soon.