An object mapper that's uber fast and lean.
August 12th 2010@shanehanna recently released a first cut of the Swift Object Mapper to rubygems. Swift has come along a fair bit since we started hacking on it as a hobby to see if we can put to rest the criticism that ruby is slow and takes up too much memory.
I ran some benchmarks this morning and found it to be 4x fast on average compared to ActiveRecord and DataMapper. It uses considerably less memory (90% less) as well. If you are inserting a lot of records, you should consider using the Swift::Adapter#write method, as it can lead to tremendous speedup (~50-80x) and memory savings.
Why reinvent the wheel you ask ? Take a look at the numbers below and you will understand. ActiveRecord and DataMapper come with a lot of features and hence some pretty heavy baggage. We realized that most of the time, all we used them for was mapping properties to fields in the database and some basic validations. We realized that we could do this in a much more simpler fashion.
More coming soon …
Swift is not as feature rich as ActiveRecord or DataMapper, it was meant to be a simple and thin abstraction. We’re planning on working on swift-more soon which would have a ton of goodies including validations, associations etc.
Also planned are adapters for SphinxSearch and Mongo. SphinxSearch 1.10 allows you to store fields directly in addition to making them searchable. We plan to either use the real-time indexing feature or xmlpipe2 to persist objects in sphinx directly.
The benchmarks
The bechmark code for each ORM,
- Creates 10,000 records at the start.
- Selects all the records from the database and goes through the results once.
- Selects all the records and updates the fields once for each record.
- GC is disabled to measure the actual memory footprint of each test run.
- ActiveRecord uses mysql2 and pg gems and Swift uses bindings to dbic++.
You can clone the repo, run the tests and see for yourself.
MySQL
benchmark sys user total rss
dm #create 0.360000 3.650000 4.010000 227.14m
dm #select 0.140000 1.880000 2.020000 128.94m
dm #update 0.710000 8.330000 9.040000 593.20m
ar #create 0.570000 5.360000 5.930000 304.77m
ar #select 0.020000 0.170000 0.190000 22.92m
ar #update 0.560000 5.710000 6.270000 322.95m
swift #create 0.310000 0.680000 0.990000 30.61m
swift #select 0.000000 0.100000 0.100000 9.32m
swift #update 0.140000 0.660000 0.800000 32.26m
swift #write 0.000000 0.070000 0.070000 6.79m
PostgreSQL
benchmark sys user total rss
dm #create 0.360000 3.560000 3.920000 245.34m
dm #select 0.110000 1.910000 2.020000 129.11m
dm #update 0.590000 7.910000 8.500000 604.77m
ar #create 1.030000 7.100000 8.130000 367.80m
ar #select 0.030000 0.320000 0.350000 38.82m
ar #update 0.800000 6.630000 7.430000 361.91m
swift #create 0.220000 0.680000 0.900000 30.60m
swift #select 0.010000 0.070000 0.080000 9.82m
swift #update 0.100000 0.890000 0.990000 32.66m
swift #write 0.000000 0.080000 0.080000 7.30m