dry-rb / dry-logic

Predicate logic with rule composition
https://dry-rb.org/gems/dry-logic/
MIT License
179 stars 66 forks source link

Specialize rule application based on curried args and arity #48

Closed flash-gordon closed 5 years ago

flash-gordon commented 5 years ago

The problem is Rule's interface makes unnecessary allocations on every call. Things like

def call(*input)

create an array for capturing arguments on every call. If the number of calls is high this becomes a bottleneck. The idea is to use a specialized version of call and [] depending on the number of curried arguments and the arity of the predicate. Benchmarking this branch in dry-types gives really prominent numbers.

flash-gordon commented 5 years ago

No kidding, this thing is fast:

v0.5.0:

Calculating -------------------------------------
type check - success      1.054M (± 4.1%) i/s -      5.297M in   5.038101s
type check - failure      1.014M (± 3.5%) i/s -      5.135M in   5.070284s
 int check - success      1.059M (± 4.7%) i/s -      5.303M in   5.021050s
 int check - failure    993.951k (± 5.7%) i/s -      5.010M in   5.059538s
 key check - success      1.016M (± 2.0%) i/s -      5.097M in   5.020833s
 key check - failure    998.392k (± 4.3%) i/s -      5.044M in   5.062710s
comparison - success      1.044M (± 4.1%) i/s -      5.267M in   5.057389s
comparison - failure      1.049M (± 3.8%) i/s -      5.293M in   5.054646s

master:

Calculating -------------------------------------
type check - success      2.781M (± 5.7%) i/s -     13.853M in   5.001125s
type check - failure    988.011k (± 5.8%) i/s -      4.997M in   5.078598s
 int check - success      2.789M (± 5.3%) i/s -     13.968M in   5.025435s
 int check - failure      1.010M (± 3.0%) i/s -      5.076M in   5.028719s
 key check - success      2.716M (± 3.2%) i/s -     13.627M in   5.023814s
 key check - failure      1.005M (± 5.5%) i/s -      5.057M in   5.052040s
comparison - success      2.759M (± 4.1%) i/s -     13.858M in   5.032949s
comparison - failure      1.040M (± 4.1%) i/s -      5.258M in   5.067956s

specialize-rule-application:

Calculating -------------------------------------
type check - success      8.333M (± 3.4%) i/s -     41.806M in   5.024341s
type check - failure      1.365M (± 5.3%) i/s -      6.811M in   5.007714s
 int check - success      8.854M (± 1.5%) i/s -     44.504M in   5.027781s
 int check - failure      1.361M (± 4.4%) i/s -      6.884M in   5.068005s
 key check - success      8.088M (± 4.9%) i/s -     40.372M in   5.006174s
 key check - failure      1.403M (± 4.4%) i/s -      7.049M in   5.034938s
comparison - success      8.236M (± 2.4%) i/s -     41.436M in   5.034580s
comparison - failure      1.426M (± 4.7%) i/s -      7.151M in   5.028299s