Posted 27 Dec 2005
Tremeur Balbous has translated some of my blog articles into French. You can find them on www.railsfrance.org.
This is great news, for me, and the French Rails community.
Merci beaucoup, Tremeur.
View Comments
Posted 19 Dec 2005
The alert reader may have noticed that I'm using my own SQL session store, which provides much better performance than the default ActiveRecordStore shipping with Rails.
I have decided to publish the source code here. If you are using Mysql, simply unpack the files into your lib directory and make SQLSessionStore your session storage.
require 'sql_session_store'
require 'mysql_session'
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.
update(:database_manager => SQLSessionStore)
SQLSessionStore.session_class = MysqlSession
If you're using components, which you probably shouldn't, you'll need to activate eager session saving:
MysqlSession.eager_session_creation = true
The improved performance is due to a number of factors:
- fixed number of known DB columns
- retrieve only fields into the session that are actually used to create the session for a controller
- offloading most of the work to the DB, including updating the created_at and updated_at fields
- hard coded Mysql statements
As a consequence, if you want another DB, other DB column names, don't want created_at or updated_at fields, you'll have to change the code.
I have uploaded HTML representations of the call trees for ActiveRecordStore and SQLSessionStore. If you inspect them closely, you'll see how much time ActiveRecordStore spends in just creating the SQL statements and how much simpler the call tree is for SQLSessionStore.
If you adapt the provided code for other database systems, I'd be happy if you sent me the code, and I'll add it to the download after reviewing. The required changes are probably pretty small, but I currently don't have the time to test other DB systems.
Enjoy!
View Comments
Posted 18 Dec 2005
It's party time! Rails 1.0 hit the streets this week.
Somehow I didn't manage to release a performance report on the new release on the very same day, as planned ..., but here it is.
Rails 1.0 performs slightly worse than the previous 0.14.1
release for my application. However, 1.0 is still much faster than the
0.13 release series.
The following performance data table shows the speed difference for
the fastest available configuration for the tested application.
/empty/index |
1.26111 | 1.40676 |
793.0 | 710.9 |
1.26 | 1.41 |
0.90 |
/welcome/index |
1.41814 | 1.57333 |
705.1 | 635.6 |
1.42 | 1.57 |
0.90 |
/rezept/index |
1.50077 | 1.66533 |
666.3 | 600.5 |
1.50 | 1.67 |
0.90 |
/rezept/myknzlpzl |
1.49374 | 1.65309 |
669.5 | 604.9 |
1.49 | 1.65 |
0.90 |
/rezept/show/713 |
3.59988 | 3.99798 |
277.8 | 250.1 |
3.60 | 4.00 |
0.90 |
/rezept/cat/Hauptspeise |
4.54024 | 4.86669 |
220.3 | 205.5 |
4.54 | 4.87 |
0.93 |
/rezept/cat/Hauptspeise?page=5 |
4.64729 | 4.97066 |
215.2 | 201.2 |
4.65 | 4.97 |
0.93 |
/rezept/letter/G |
4.59054 | 4.84387 |
217.8 | 206.4 |
4.59 | 4.84 |
0.95 |
c1: 0.14.1, c2: 1.0, r/s: requests per second, ms/r: milliseconds per request |
The reasons for this significant slowdown have been identified and
are being worked on (tickets 3155 and 3174).
You can find additional information and lots of performance data in the
full report.
View Comments
Posted 06 Dec 2005
The 0.14 Rails series includes a new option setting for template rendering, which allows for reducing the number of newlines generated by template processing. It's a string valued class attribute for ActionView, called erb_trim_mode. Its value is passed to the ERB compiler when a template gets compiled, with a default value of "-".
Some documentation for possible settings is part of the ERB class doc.
However, the doc is incomplete, as it doesn't mention Rails' default setting "-".
erb_trim_mode affects the way template processing handles newline characters in the template. Per default, (when erb_trim_mode is set to nil), processing leaves all newline characters occurring in the template in the generated html code. Which means that many extraneous newlines get inserted into your output.
For example,
<% if expr %>
some text
<% else %>
other text
<% end %>
will generate the following processing code:
if expr ; _erbout.concat("\n")
_erbout.concat("some text\n")
else ; _erbout.concat("\n")
_erbout.concat("other text\n")
end ; _erbout.concat("\n")
With the default setting of erb_trim_mode, you can suppress extraneous newline characters by adding a - before the closing %>:
<% if expr -%>
some text
<% else -%>
other text
<% end -%>
will generate the following template code:
if expr
_erbout.concat("some text\n")
else
_erbout.concat("other text\n")
end
This version looks much cleaner, suppresses 2 superfluous newline characters in the generated HTML code and saves 2 function calls when processed. Which is no big deal, unless the above call occurs inside a loop. If the loop body gets executed 100 times, you have already saved 200 characters and, more importantly, 200 function calls.
Manually adding all the minuses to closing %> markup is somewhat tedious. erb_trim_mode comes to rescue: if set to ">", newline characters will be suppressed for <%...%> markup closing a line; if set to "<>", newline characters will be suppressed for <%...%> occurring as a line of its own.
I have measured the relative performance of setting erb_trim_mode to ">". The following table shows that my app's pages receive a performance increase ranging from 1 to 4%.
configuration 1: 12-06.uncached.untrimmed
requests=1000, options=-bm=uncached -lib=r141 -mysql_session
-fast_routes -fast_readers
configuration 2: 12-06.uncached.trimmed
requests=1000, options=-bm=uncached -lib=r141 -mysql_session
-fast_routes -fast_readers -trim
page c1 real c2 real c1 r/s c2 r/s c1 ms/r c2 ms/r c1/c2
1: 3.52722 3.47518 283.5 287.8 3.53 3.48 1.01
2: 4.30330 4.26213 232.4 234.6 4.30 4.26 1.01
3: 4.49761 4.36027 222.3 229.3 4.50 4.36 1.03
4: 4.45229 4.27840 224.6 233.7 4.45 4.28 1.04
urls:
1: /rezept/show/713
2: /rezept/cat/Hauptspeise
3: /rezept/cat/Hauptspeise?page=5
4: /rezept/letter/G
Unfortunately, ERB doesn't support combining the "-" and ">" setting. So you'll have to decide which way to go upfront. If you choose on ">", you may find that you have to add empty lines in some places where they weren't needed before.
View Comments
Posted 28 Nov 2005
Using Rails 0.14 and onward, you can give your app a slight performance boost by not loading parts of the framework that you don't need. For example, if you don't expose parts of your app as a web service, then you don't need to load
actionwebservice. Likewise, if you don't send mail from your app, you don't need to load
actionmailer.
If you're using the Rails initializer to start your app, you can do it like so:
Rails::Initializer.run do |config|
# Skip frameworks you're not going to use
config.frameworks -= [ :action_web_service, :action_mailer ]
...
end
If you're still using an old
environment.rb, just comment out the corresponding require lines:
# Require Rails libraries.
require 'active_support'
require 'active_record'
require 'action_controller'
# require 'action_mailer'
# require 'action_web_service'
Additionally, you should also load only the database adapters for the database(s) which you are using. Add the following to your
environment.rb, before Rails gets required:
RAILS_CONNECTION_ADAPTERS = %w(mysql)
By default, Rails will load all connection adapters it can find.
Minimizing your code footprint will speed up Rails, because Ruby traverses all abstract syntax trees stored on the heap during garbage collection. If you can avoid loading significantly sized code, you will reduce the memory footprint of your app, thereby speeding up garbage collection. It might also help to increase object lookup at runtime due to smaller sized data structures containing meta information.
View Comments