Ticket #3238: db_benchmark.rb
| File db_benchmark.rb, 3.0 kB (added by argv <lsegal@holycraplions.com>, 3 years ago) |
|---|
| 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 |