ReactiveX / RxGroovy

RxJava bindings for Groovy
Apache License 2.0
158 stars 25 forks source link

Use groovy call sites to call back into the Observable methods. #6

Closed abersnaze closed 9 years ago

abersnaze commented 9 years ago

Methods on rx.Observable that have an argument that take a rx.function.Function can't be extended with groovy extensions.

The RxGroovy extension adds new groovy.lang.Closure version of each method on rx.Observable that has rx.function.Function as an argument. When the closure version is invoked it wraps the closure in a function and invokes the java.lang.reflect.Method directly bypassing any attempt to extend the original.

This PR changes the invoke to use groovy's internal method resolution and caching. This allows additional groovy extensions to be applied. If no extension are present it will use custom generated bytecode to avoid doing reflection.

################## BEFORE

# Run complete. Total time: 00:03:17

Benchmark                        (size)               (source)   Mode   Samples        Score  Score error    Units
r.l.g.ExtensionPerf.extension         1      in.map({ it + 1})  thrpt         5  3212878.269    29678.977    ops/s
r.l.g.ExtensionPerf.extension         1 in.filter({ it != 0 })  thrpt         5  3497772.417   534053.736    ops/s
r.l.g.ExtensionPerf.extension      1000      in.map({ it + 1})  thrpt         5    18137.493      432.222    ops/s
r.l.g.ExtensionPerf.extension      1000 in.filter({ it != 0 })  thrpt         5    19746.618      886.572    ops/s
r.l.g.ExtensionPerf.extension   1000000      in.map({ it + 1})  thrpt         5       18.842        0.346    ops/s
r.l.g.ExtensionPerf.extension   1000000 in.filter({ it != 0 })  thrpt         5       19.297        0.673    ops/s

################## AFTER

# Run complete. Total time: 00:03:17

Benchmark                        (size)               (source)   Mode   Samples        Score  Score error    Units
r.l.g.ExtensionPerf.extension         1      in.map({ it + 1})  thrpt         5  4036047.884   117545.855    ops/s
r.l.g.ExtensionPerf.extension         1 in.filter({ it != 0 })  thrpt         5  4161935.126   131375.955    ops/s
r.l.g.ExtensionPerf.extension      1000      in.map({ it + 1})  thrpt         5    19015.365     1228.843    ops/s
r.l.g.ExtensionPerf.extension      1000 in.filter({ it != 0 })  thrpt         5    19754.786      263.644    ops/s
r.l.g.ExtensionPerf.extension   1000000      in.map({ it + 1})  thrpt         5       17.685        6.204    ops/s
r.l.g.ExtensionPerf.extension   1000000 in.filter({ it != 0 })  thrpt         5       18.208        3.433    ops/s