|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) |
| 4 | + |
| 5 | +require 'benchmark' |
| 6 | +require 'ruby-enum' |
| 7 | + |
| 8 | +## |
| 9 | +# Ruby::Enum equivalent of a plain Hash/constant lookup. |
| 10 | +class Colors |
| 11 | + include Ruby::Enum |
| 12 | + |
| 13 | + define :RED, 'red' |
| 14 | + define :GREEN, 'green' |
| 15 | + define :BLUE, 'blue' |
| 16 | +end |
| 17 | + |
| 18 | +# Plain Ruby equivalents, doing the same lookups without Ruby::Enum. |
| 19 | +PLAIN_HASH = { RED: 'red', GREEN: 'green', BLUE: 'blue' }.freeze |
| 20 | + |
| 21 | +module PlainConstants |
| 22 | + RED = 'red' |
| 23 | + GREEN = 'green' |
| 24 | + BLUE = 'blue' |
| 25 | +end |
| 26 | + |
| 27 | +n = 1_000_000 |
| 28 | + |
| 29 | +def benchmark(label, iterations, &block) |
| 30 | + time = Benchmark.realtime { iterations.times(&block) } |
| 31 | + puts "#{label}: #{time.round(4)}" |
| 32 | + time |
| 33 | +end |
| 34 | + |
| 35 | +puts "Running #{n} iterations of each scenario below\n\n" |
| 36 | + |
| 37 | +puts '--- Constant access ---' |
| 38 | +enum_const_time = benchmark('Ruby::Enum constant (Colors::RED)', n) { Colors::RED } |
| 39 | +plain_const_time = benchmark('plain Ruby constant (PlainConstants::RED)', n) { PlainConstants::RED } |
| 40 | + |
| 41 | +puts "\n--- Key to value lookup ---" |
| 42 | +enum_value_time = benchmark('Ruby::Enum (Colors.value(:RED))', n) { Colors.value(:RED) } |
| 43 | +hash_value_time = benchmark('plain Hash (PLAIN_HASH[:RED])', n) { PLAIN_HASH[:RED] } |
| 44 | + |
| 45 | +puts "\n--- Value to key lookup ---" |
| 46 | +benchmark('Ruby::Enum (Colors.key(\'red\'))', n) { Colors.key('red') } |
| 47 | +benchmark('plain Hash (PLAIN_HASH.key(\'red\'))', n) { PLAIN_HASH.key('red') } |
| 48 | + |
| 49 | +puts "\n--- Existence checks ---" |
| 50 | +benchmark('Ruby::Enum (Colors.key?(:RED))', n) { Colors.key?(:RED) } |
| 51 | +benchmark('plain Hash (PLAIN_HASH.key?(:RED))', n) { PLAIN_HASH.key?(:RED) } |
| 52 | + |
| 53 | +puts "\n--- Enumerating all keys/values ---" |
| 54 | +benchmark('Ruby::Enum (Colors.keys)', n) { Colors.keys } |
| 55 | +benchmark('plain Hash (PLAIN_HASH.keys)', n) { PLAIN_HASH.keys } |
| 56 | +benchmark('Ruby::Enum (Colors.values)', n) { Colors.values } |
| 57 | +benchmark('plain Hash (PLAIN_HASH.values)', n) { PLAIN_HASH.values } |
| 58 | + |
| 59 | +puts "\n--- Comparison ---" |
| 60 | +puts "Ruby::Enum constant access is #{(enum_const_time / plain_const_time).round(2)}x plain Ruby constant access" |
| 61 | +puts "Ruby::Enum .value is #{(enum_value_time / hash_value_time).round(2)}x plain Hash#[]" |
0 commit comments