Previous: Threading, Up: Tutorial

2.16 Performance Tips

Performance is usually measured in transactions per second. Database reads are cheap. To get more transactions throughput, consider setting

     * (db-env-set-flags (controller-environment *store-controller*) 1
                         :txn-nosync t)

or look at other flags in the sleepycat docs. This will greatly increase your throughput at the cost of some durability; I get around a 100x improvement. Durability can be recovered with judicious use of checkpointing and replication, though this is currently not supported directly by Elephant – see the sleepycat docs.

The serializer is definitely fast on fixnums, strings, and persistent things. It is fast but consing with floats and doubles. YMMV with other values, though I've tried to make them fast.

Using *auto-commit* and not with-transactions is a great way to have a huge number of transactions. You'll find that

     (dotimes (i 1000) (add-to-root "key" "value"))

is much slower than

     (let ((*auto-commit* nil))
      (with-transaction ()
       (dotimes (i 1000) (add-to-root "key" "value"))))

since there's only 1 transaction in the latter. However storing transaction state requires allocated main memory of which there is a finite amount so do not make your transactions too large.

Use the persistent classes and collections; if you're using transactions correctly they should be much faster.

If you don't need transactions you can turn them off. Opening the DB in less concurrent / transactional modes will be supported very soon (it's just an argument change, I think.) However you will need to ensure that multiple threads do not interleave access so single user mode is not suitable for use in web servers or other typically multi-threaded applications.