rethinkdb/rethinkdb — pull request #1842 by nviennot (2014-01-10 13:37:57+00:00)
Title: Ruby driver optimizations

I'm trying to optimize the Ruby driver due to its poor performance: https://github.com/rethinkdb/rethinkdb/issues/1798

One of the issue is that building queries is really long.

Consider this benchmark:

```ruby
require 'rethinkdb'
require 'benchmark'
extend RethinkDB::Shortcuts
puts Benchmark.measure { 10000.times { r.table("users").filter({:attr => "123"}).orderby(r.asc("id")).limit(10).to_pb } }
```

On my machine with ruby2.0p353:

On the `next` branch, the average time to build the query is `0.55ms`.
With the "don't parse the backtrace all the time" commit, it drops to `0.31ms`.
With the "Refactored the RQL methods" commit, which precompiles all the RQL commands, it drops to `0.27ms`.
If we were to make no calls to `caller` to retrieve the backtrace, it would drop to `0.18ms`.

Having the backtrace is nice (which is only used in the case of an error), but is ridiculously expensive.
Note that this test is running with a very small backtrace, but on a real application, the backtrace will be much larger. It's not uncommon to see a backtrace depth of 100 functions in a web application when hitting a controller with instrumentation all around the place.

Taking the `0.27ms` baseline (with the two commits merged in), when I run the benchmark in a fresh Ruby-on-Rails console instead of its own process, the average time jumps to `1.2ms`. This is really sad.
When removing references to `caller`, it goes down to `0.58ms` which is still sad. I don't understand why I'm not getting the previous `0.18ms`, it's probably due to all the crap that gets injected in some core classes.

Regardless, I think the nice to have backtrace feature is not worth the `0.6ms` of overhead.

It might even be worth considering some sort of query caching, perhaps like redis: http://redis.io/commands/evalsha or postgresql: http://www.postgresql.org/docs/9.2/static/sql-prepare.html