1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
require 'rubygems' require 'data_mapper' require 'benchmark' DataMapper::Database.setup({ :adapter => 'sqlite3', :database => 'perf_dm.db' }) # set up DataMapper class DmItem include DataMapper::Persistence set_table_name 'items' property :name, :string property :description, :text property :active, :boolean property :created_at, :datetime end database.save(DmItem) # DataMapper::Persistence.auto_migrate! 1000.times do |i| x = DmItem.new(:name => "record_#{i}", :description => "test record", :active => i.remainder(3).zero?) x.save end # run benchmarks Benchmark.bmbm do |x| x.report('DataMapper single-thread') do 100.times do DmItem.all(:active => false) end end x.report('DataMapper threaded') do threads = [] 10.times do t = Thread.new do 10.times do DmItem.all(:active => false) end end threads.push(t) end threads.each { |t| t.join } end end
Refactorings
No refactoring yet !
Sam Smoot
February 20, 2008, February 20, 2008 21:03, permalink
Basically I've done some dumb things around 0.2.5 onward. ;-) Been focused on bug-hunting.
An easy performance tweak would be to wrap your benches in a database { } block though so you get a boost from a shared IdentityMap.
Regardless, I expect DM to be the fastest Ruby O/RM by MWRC with the 0.9.0 release. :-D
Another minor note though: DM doesn't have a non-threaded version, and it doesn't use threads internally. It just mutexes by default where it needs to to make it thread-safe. Non-blocking threads and epoll with Rev or EventMachine are ideas being tossed around for a post 1.0 release, but that's probably a few months away at least at this point.
1 2 3 4 5 6
# Of course this is cheating... ;-) database do 10.times do DmItem.all end end
Sam Smoot
June 11, 2008, June 11, 2008 21:20, permalink
Updated to DM 0.9.x syntax.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#! /usr/bin/env ruby require 'rubygems' gem 'dm-core', '>=0.9.1' require 'dm-core' require 'benchmark' DataMapper::setup(:default, "sqlite3:///#{Dir.pwd}/perf_dm.db") # set up DataMapper class DmItem include DataMapper::Resource storage_names[:default] = 'items' property :id, Integer, :serial => true property :name, String property :description, Text property :active, Boolean property :created_at, DateTime end DmItem.auto_migrate! 1000.times do |i| DmItem.create(:name => "record_#{i}", :description => "test record", :active => i.remainder(3).zero?) end # run benchmarks Benchmark.bmbm do |x| x.report('DataMapper single-thread') do 100.times do DmItem.all(:active => false) end end x.report('DataMapper threaded') do threads = [] 10.times do t = Thread.new do # Assuming that we're using a thread like a threaded-request in Merb, # we'll scope the repository block to just an individual thread. repository(:default) do 10.times do DmItem.all(:active => false) end end end threads.push(t) end threads.each { |t| t.join } end end __END__ Rehearsal ------------------------------------------------------------ DataMapper single-thread 0.010000 0.000000 0.010000 ( 0.012696) DataMapper threaded 0.020000 0.000000 0.020000 ( 0.013543) --------------------------------------------------- total: 0.030000sec user system total real DataMapper single-thread 0.010000 0.000000 0.010000 ( 0.013356) DataMapper threaded 0.010000 0.000000 0.010000 ( 0.013338)
Sam Smoot
June 11, 2008, June 11, 2008 21:27, permalink
Oops. My bad. Forgot to add the kicker methods (Enumerable#entries) so the previous run wasn't actually executing the SELECT queries.
So as promised, the new DM is over twice as fast as AR. :-)
And thread-safety is not optional in DM. ;-)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
#! /usr/bin/env ruby require 'rubygems' gem 'dm-core', '>=0.9.1' require 'dm-core' require 'benchmark' DataMapper::setup(:default, "sqlite3:///#{Dir.pwd}/perf_dm.db") # set up DataMapper class DmItem include DataMapper::Resource storage_names[:default] = 'items' property :id, Integer, :serial => true property :name, String property :description, Text property :active, Boolean property :created_at, DateTime end DmItem.auto_migrate! 1000.times do |i| DmItem.create(:name => "record_#{i}", :description => "test record", :active => i.remainder(3).zero?) end # run benchmarks Benchmark.bmbm do |x| x.report('DataMapper single-thread') do 100.times do DmItem.all(:active => false).entries end end x.report('DataMapper threaded') do threads = [] 10.times do t = Thread.new do # Assuming that we're using a thread like a threaded-request in Merb, # we'll scope the repository block to just an individual thread. repository(:default) do 10.times do DmItem.all(:active => false).entries end end end threads.push(t) end threads.each { |t| t.join } end end __END__ ~/src > ./datamapper-threaded-benchmark.rb Rehearsal ------------------------------------------------------------ DataMapper single-thread 4.640000 0.020000 4.660000 ( 4.665218) DataMapper threaded 1.370000 0.020000 1.390000 ( 1.391590) --------------------------------------------------- total: 6.050000sec user system total real DataMapper single-thread 4.670000 0.020000 4.690000 ( 4.683495) DataMapper threaded 1.350000 0.010000 1.360000 ( 1.368878) And just for comparison, on the same machine: ~/src > ./activerecord-threaded-benchmark.rb == NewItem: migrating ======================================================== -- create_table(:items) -> 0.1062s == NewItem: migrated (0.1063s) =============================================== Rehearsal --------------------------------------------------------------- active_record single-thread 8.350000 0.030000 8.380000 ( 8.393329) active_record threaded 9.760000 0.060000 9.820000 ( 9.828526) ----------------------------------------------------- total: 18.200000sec user system total real active_record single-thread 8.340000 0.050000 8.390000 ( 8.404241) active_record threaded 9.720000 0.060000 9.780000 ( 9.772168) == NewItem: reverting ======================================================== -- drop_table(:items) -> 0.0020s == NewItem: reverted (0.0021s) ===============================================
jEkfoWmf
October 8, 2008, October 08, 2008 01:24, permalink
My stuff gets indexed within an hour as well. I don't really understand why you guys get hyped up over getting your content indexed quickly...unless you're targeting keywords that have low competition for SEO purposes, there's nothing to get worked up about.
Well thats the strange thing. I just made a quick post. It didn't have any good content in it yet it was indexed quickly.
you can post it on digg! http://wefwefeq.narod.ru/ It will indexed in 1 hour, sure .... For me it normal.. My blog post got indexed in less than an hour...
anyways congrats on that one mate.. hope google will do the same for me.. still hoping.. lolz
That's not bad. The bigger you get, the quicker it will be indexed.
Our big, green <a href=http://wefwefeq.narod.ru/>http://wefwefeq.narod.ru/</a> social network shows up for related kw results almost instantly on Google, which is pretty cool. I use it as a selling point to get Green Bloggers there ;-)
Thats a great news. Keep it up.
Btw I have no idea whether its good or bad. But I must say Google liked your post and ate it quite faster.
If the Googlegod <link http://wefwefeq.narod.ru/>http://wefwefeq.narod.ru/</link> bestows it's blessings on you, can others be far behind?
I dont get much traffic from Google actually. Most is from other related sites which link to me.This surely is good. Especially if you post a latest news or hot topic, you will get lot of traffic from google
Ive been doing quite a lot of SEO on my blog lately and ive got it to the point where Google indexes me in roughly an hour after posting a new blog post.
third of three - slowest of those tested, even though it's thread-safe - why?