Didn’t have the time to write a “real” readme, but let me show you …
A short comparison
Use Case:
class Content < Lore::Model
table :contents, :public
primary_key :id, :content_id_seq
end
class Article < Lore::Model
table :articles, :public
primary_key :id, :article_id_seq
is_a Content, :content_id
end
Selecting Articles using ActiveRecord
Article.find(:all, :include => :content,
:conditions => "id between 1 AND 100")
Selecting Articles using Sequel
DB[:articles].left_outer_join(:contents, :id => :content_id).filter( :articles__id => (1..100))
Selecting Articles using Lore
Article.all_with(Article.id.in(1..100))
(joins Content automatically)
Benchmark results (1000 queries each returning 100 rows)
Most recent benchmark results from lore/benchmark/results.txt, generated by running
ruby lore/benchmarks/select.rb 1000
Output on my machine:
Rehearsal ------------------------------------------------------------
unprocessed query 0.030000 0.030000 0.060000 ( 1.269820)
result fetching in lore 0.400000 0.050000 0.450000 ( 1.661275)
result parsing in lore 0.540000 0.080000 0.620000 ( 3.600497)
ac_instances unfiltered 2.440000 0.430000 2.870000 ( 4.113851)
ac_instances filtered 4.650000 0.700000 5.350000 ( 6.601500)
lore select unfiltered 2.720000 0.330000 3.050000 ( 4.355712)
lore shortcut filtered 5.110000 0.790000 5.900000 ( 7.507479)
--> lore shortcut unfiltered 3.030000 0.420000 3.450000 ( 4.675418) <--
--> activerecord 15.060000 1.960000 17.020000 ( 22.098705) <--
--> sequel 8.400000 0.940000 9.340000 ( 11.373551) <--
lore using cache 2.060000 0.080000 2.140000 ( 2.131782)
lore prepared 2.400000 0.460000 2.860000 ( 4.334760)
-------------------------------------------------- total: 53.110000sec
user system total real
unprocessed query 0.040000 0.020000 0.060000 ( 1.255553)
result fetching in lore 0.380000 0.050000 0.430000 ( 1.731519)
result parsing in lore 0.600000 0.120000 0.720000 ( 3.630439)
ac_instances unfiltered 2.580000 0.330000 2.910000 ( 4.138985)
ac_instances filtered 4.660000 0.710000 5.370000 ( 6.590051)
lore select unfiltered 2.640000 0.490000 3.130000 ( 4.357413)
lore shortcut filtered 5.150000 0.760000 5.910000 ( 7.518942)
lore shortcut unfiltered 2.660000 0.450000 3.110000 ( 4.647531)
activerecord 15.330000 2.180000 17.510000 ( 22.384284)
sequel 8.470000 0.880000 9.350000 ( 11.396475)
lore using cache 2.070000 0.070000 2.140000 ( 2.137200)
lore prepared 2.610000 0.390000 3.000000 ( 4.199908)
NOTE: Perhaps results for AR and Sequel can be improved by doing things differently - i’m using default behaviours for benchmarking, but all SQL queries look alright, so my benchmark code can’t be that wrong. If you know how to optimize my usage or AR and Sequel, please let me know!
Also be aware that most applications aren’t slow because of its ORM, but because of … sub-optimal algorithms using them. Don’t choose an ORM just because of a benchmark.
I just want to state that an ORM with both great performance and convenient usage is feasible, and Lore is an example.
Apart from that: In case you don’t like Lore, use Sequel. It’s incredibly stable, well-maintained, not that inefficient and inconvenient as AR (see above), and its maintainer is a nice guy - which is more important than you might think.