Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #3238: db_benchmark.rb

File db_benchmark.rb, 3.0 kB (added by argv <lsegal@holycraplions.com>, 3 years ago)

Benchmarking script along with my results listed in the comments

Line 
1 #!/usr/bin/ruby
2 # Place this benchmark in activerecord/benchmarks
3 # Replace base.rb with patched version to see results for new ActiveRecord::Base
4 #
5 # My Results (for MySQL):
6 #
7 # Using old base.rb (100 runs):
8 #               user     system      total        real
9 # No save  :  0.270000   0.020000   0.290000 (  0.402543)
10 # With save:  3.600000   0.260000   3.860000 (  5.091319)
11 #
12 # Modified (patched, track_inplace_modifications = false) base.rb (100 queries):
13 #               user     system      total        real
14 # No save  :  0.300000   0.020000   0.320000 (  0.390043)
15 # With save:  1.970000   0.120000   2.090000 (  2.420767)
16 #
17 # Modified (patched, track_inplace_modifications = true) base.rb (100 queries):
18 #               user     system      total        real
19 # No save  :  0.400000   0.020000   0.420000 (  0.598095)
20 # With save:  3.300000   0.230000   3.530000 (  4.495584)
21 #
22 # You can see that without in place modifications, the performance increase over SQL queries is
23 # very significant (2 seconds on just 100 runs). There's also no slowdown on reading.
24 # Of course, it's better to focus on the worst case scenario, so let's:
25 #
26 # Changes with in place modification tracking turned on indicate a slight slowdown in reading values
27 # (each record reads _all_ attributes and doubles memory size) but actually shows a slight
28 # increase in the saving run. This means that the SQL query optimization is there, and visible too--
29 # 0.5 sec increase on only 100 runs. And it outweighs the performance loss, so all in all, it's a good thing.
30 #
31 # By the way, if you're curious, the algorithm runs in O(n), meaning increasing the amount
32 # of queries to 1000 will raise the benchmark times by approx. 10-- but the relationships stay.
33 # Try it!
34 #
35 # Example (unpatched base.rb) for 1000 runs:
36 #               user     system      total        real
37 # No save  :  2.580000   0.180000   2.760000 (  3.709316)
38 # With save: 36.130000   2.610000  38.740000 ( 55.599461)
39 #
40 # Example (patched base.rb, track_inplace_modifications = false) for 1000 runs:
41 #               user     system      total        real
42 # No save  :  3.060000   0.160000   3.220000 (  3.815927)
43 # With save: 19.580000   1.260000  20.840000 ( 25.586016)
44 #
45 # Example (patched base.rb, track_inplace_modifications = true) for 1000 runs:
46 #               user     system      total        real
47 # No save  :  4.080000   0.210000   4.290000 (  5.359764)
48 # With save: 32.920000   2.260000  35.180000 ( 46.913362)
49 #
50
51 $:.unshift(File.dirname(__FILE__) + '/../lib')
52 if ARGV[2]
53   require 'rubygems'
54   require_gem 'activerecord', ARGV[2]
55 else
56   require 'active_record'
57 end
58 QUOTED_TYPE = '`type`'
59 require '../test/fixtures/company'
60
61 ActiveRecord::Base.establish_connection(:adapter => "mysql", :database => "activerecord_unittest")
62
63 require 'benchmark'
64 p = Proc.new do |do_save|
65   1000.times do
66     companies = Company.find(:all)
67     companies.each do |c|
68       c.class.column_names.each {|col| c[col] }
69       c.save if do_save
70     end
71   end
72 end
73 Benchmark.bm do |b|
74   b.report("No save  :") { p.call(false) }
75   b.report("With save:") { p.call(true) }
76 end