ostruct
ostruct copied to clipboard
Avoid defining singleton methods
This PR only creates new singleton methods when they are needed for overwriting an existing instance method. It should be mostly backward-compatible with the current OpenStruct implementation, but I suspect there are some minor incompatibilities (which may be significant).
I believe this should generally be a significant performance improvement. I'm guessing that OpenStruct objects are generally ephemeral and their attributes are generally read fewer than a dozen times on average. In my benchmarks, that wasn't enough for the benefits of defining singleton methods to outweigh the costs. All of the benchmarks I created, except for 100x reads, showed the same or better performance.
And that's mostly ignoring any non-local costs to constantly busting method caches. This PR should almost completely remove that cost.
$ benchmark-driver benchmarks/ostruct.yml
Warming up --------------------------------------
new 7.047k i/s - 7.711k times in 1.094212s (141.90μs/i)
attr_write_read 4.904k i/s - 4.910k times in 1.001289s (203.93μs/i)
index_write_attr_read 6.346k i/s - 6.963k times in 1.097167s (157.57μs/i)
null_reads 79.488k i/s - 85.250k times in 1.072495s (12.58μs/i)
10x_reads 6.651k i/s - 7.282k times in 1.094836s (150.35μs/i)
100x_reads 5.136k i/s - 5.150k times in 1.002780s (194.71μs/i)
Calculating -------------------------------------
v0.6.0 local
new 6.938k 33.067k i/s - 21.141k times in 3.047342s 0.639334s
attr_write_read 4.886k 14.021k i/s - 14.711k times in 3.010686s 1.049232s
index_write_attr_read 6.270k 20.225k i/s - 19.039k times in 3.036489s 0.941373s
null_reads 78.351k 77.187k i/s - 238.462k times in 3.043491s 3.089414s
10x_reads 6.518k 13.306k i/s - 19.953k times in 3.061390s 1.499576s
100x_reads 4.454k 2.078k i/s - 15.407k times in 3.459125s 7.414447s
Comparison:
new
local: 33067.2 i/s
v0.6.0: 6937.5 i/s - 4.77x slower
attr_write_read
local: 14020.7 i/s
v0.6.0: 4886.3 i/s - 2.87x slower
index_write_attr_read
local: 20224.7 i/s
v0.6.0: 6270.1 i/s - 3.23x slower
null_reads
v0.6.0: 78351.5 i/s
local: 77186.8 i/s - 1.02x slower
10x_reads
local: 13305.8 i/s
v0.6.0: 6517.6 i/s - 2.04x slower
100x_reads
v0.6.0: 4454.0 i/s
local: 2078.0 i/s - 2.14x slower