orocos-toolchain/utilrb — pull request #9 by doudou (2014-10-08 23:31:32+00:00)
Title: Optimize validate options

Kernel.validate_options is used very extensively, and as such its performance is actually very important. I already had a few cases where the call to validate_options was a non-negligible performance hit.

This commit optimizes the underlying filter_options method for the common case, without changing the method semantics. Some more optimizations could be performed if we drop some of the methods "magic features", but that would be for another commit (after a proper deprecation period).

The new benchmark file checks the validate_options performance in different situations, as well as against ruby 2.0+ keyword arguments

The result before the change is (for 100_000 method calls, i.e. numbers are *10 microseconds/call)

user system total real
with empty options 1.840000 0.000000 1.840000 ( 1.842431)
with empty options and new-style hash 1.810000 0.000000 1.810000 ( 1.820675)
with empty options and keyword arguments 0.430000 0.000000 0.430000 ( 0.433547)
with all options set 2.280000 0.000000 2.280000 ( 2.276723)
with all options set and new-style hash 2.280000 0.000000 2.280000 ( 2.284068)
with all options set and keyword arguments 0.420000 0.000000 0.420000 ( 0.421685)

With the optimizations, we get instead

user system total real
with empty options 0.850000 0.000000 0.850000 ( 0.867771)
with empty options and new-style hash 0.830000 0.000000 0.830000 ( 0.835507)
with empty options and keyword arguments 0.430000 0.000000 0.430000 ( 0.433907)
with all options set 0.860000 0.000000 0.860000 ( 0.867791)
with all options set and new-style hash 0.900000 0.000000 0.900000 ( 0.904429)
with all options set and keyword arguments 0.420000 0.000000 0.420000 ( 0.422405)

The new implementation is 0(1) in the size of the options hash and O(N) in the size of the expected arguments. It also avoids the creation of additional string objects if the provided hash(es) have symbol keys (the very common case)