diff --git a/README.md b/README.md index 11977e0..9ac514a 100644 --- a/README.md +++ b/README.md @@ -492,18 +492,18 @@ Comparison: ``` $ ruby -v code/enumerable/each_with_index-vs-while-loop.rb -ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin14] - +ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux] Calculating ------------------------------------- - While Loop 22.553k i/100ms - each_with_index 11.963k i/100ms -------------------------------------------------- - While Loop 240.752k (± 7.1%) i/s - 1.218M - each_with_index 126.753k (± 5.9%) i/s - 634.039k + While optimal 443.606 (± 2.5%) i/s - 2.250k in 5.075720s + While cached size 441.961 (± 0.5%) i/s - 2.244k in 5.077426s + While loop 363.202 (± 3.3%) i/s - 1.836k in 5.061400s + each_with_index 277.373 (± 1.1%) i/s - 1.404k in 5.062208s Comparison: - While Loop: 240752.1 i/s - each_with_index: 126753.4 i/s - 1.90x slower + While optimal: 443.6 i/s + While cached size: 442.0 i/s - same-ish: difference falls within error + While loop: 363.2 i/s - 1.22x slower + each_with_index: 277.4 i/s - 1.60x slower ``` ##### `Enumerable#map`...`Array#flatten` vs `Enumerable#flat_map` [code](code/enumerable/map-flatten-vs-flat_map.rb) @@ -1303,6 +1303,27 @@ Comparison: Time.parse: 43710.9 i/s - 2.62x slower ``` +##### `Time#+` vs `Time.at(Time#to_f+)` [code](code/time/plus-vs-to_f-plus.rb) + +This covers both high and low precision since high precision operations are more expensive. +Time#+ is slow because it calls Float#to_r and does a bunch of Bignum operations to avoid overflowing if the offset is ever insanely high. + +``` +$ ruby -v code/time/plus-vs-to_f-plus.rb +ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux] +Calculating ------------------------------------- + Time#to_f+ (low) 1.485k (± 1.5%) i/s - 7.548k in 5.084706s + Time#+ (low) 854.005 (± 4.2%) i/s - 4.300k in 5.046595s + Time#to_f+ (high) 1.051k (± 1.4%) i/s - 5.355k in 5.094035s + Time#+ (high) 836.424 (± 7.7%) i/s - 4.165k in 5.021368s + +Comparison: + Time#to_f+ (low): 1484.8 i/s + Time#to_f+ (high): 1051.4 i/s - 1.41x slower + Time#+ (low): 854.0 i/s - 1.74x slower (3.11x on i386-mingw32) + Time#+ (high): 836.4 i/s - 1.78x slower (3.02x on i386-mingw32) +``` + ### Range #### `cover?` vs `include?` [code](code/range/cover-vs-include.rb) diff --git a/code/enumerable/each_with_index-vs-while-loop.rb b/code/enumerable/each_with_index-vs-while-loop.rb index 4cf3f3e..3626749 100644 --- a/code/enumerable/each_with_index-vs-while-loop.rb +++ b/code/enumerable/each_with_index-vs-while-loop.rb @@ -2,6 +2,27 @@ ARRAY = [*1..100] +def fastest + array = ARRAY + index = 0 + size = array.size + while index < size + array[index] + index + index += 1 + end + array +end + +def faster + index = 0 + size = ARRAY.size + while index < size + ARRAY[index] + index + index += 1 + end + ARRAY +end + def fast index = 0 while index < ARRAY.size @@ -18,7 +39,9 @@ def slow end Benchmark.ips do |x| - x.report("While Loop") { fast } - x.report("each_with_index") { slow } + x.report("While optimal", 'fastest;' * 1000) + x.report("While cached size", 'faster;' * 1000) + x.report("While simple", 'fast;' * 1000) + x.report("each_with_index", 'slow;' * 1000) x.compare! end diff --git a/code/time/plus-vs-to_f-plus.rb b/code/time/plus-vs-to_f-plus.rb new file mode 100644 index 0000000..88c7fec --- /dev/null +++ b/code/time/plus-vs-to_f-plus.rb @@ -0,0 +1,33 @@ +require 'benchmark/ips' + +TimeFloatLowPrecision = 1525262447.0 +OffsetFloatLowPrecision = 1.1 +TimeFloatHighPrecision = 1525262447.1234567 +OffsetFloatHighPrecision = 1.1234567 + +TimeLowPrecision = Time.at(TimeFloatLowPrecision) +TimeHighPrecision = Time.at(TimeFloatHighPrecision) + +def fast_low_precision + Time.at(TimeLowPrecision.to_f + OffsetFloatLowPrecision) +end + +def slow_low_precision + TimeLowPrecision + OffsetFloatLowPrecision +end + +def fast_high_precision + Time.at(TimeHighPrecision.to_f + OffsetFloatHighPrecision) +end + +def slow_high_precision + TimeHighPrecision + OffsetFloatHighPrecision +end + +Benchmark.ips do |x| + x.report('Time#to_f+ (low)', 'fast_low_precision;' * 1000) + x.report('Time#+ (low)', 'slow_low_precision;' * 1000) + x.report('Time#to_f+ (high)', 'fast_high_precision;' * 1000) + x.report('Time#+ (high)', 'slow_high_precision;' * 1000) + x.compare! +end \ No newline at end of file