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.