Skip to content

Commit 202507c

Browse files
committed
Add benchmarks
1 parent 00e895f commit 202507c

3 files changed

Lines changed: 62 additions & 1 deletion

File tree

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Enum-like behavior for Ruby, heavily inspired by [this](http://www.rubyfleebie.c
2525
- [Duplicate enumerator keys or duplicate values](#duplicate-enumerator-keys-or-duplicate-values)
2626
- [Inheritance](#inheritance)
2727
- [Exhaustive case matcher](#exhaustive-case-matcher)
28+
- [Benchmarks](#benchmarks)
2829
- [Contributing](#contributing)
2930
- [Copyright and License](#copyright-and-license)
3031
- [Related Projects](#related-projects)
@@ -264,7 +265,7 @@ ShippedOrderState.values # ['CREATED', 'PAID', 'PREPARED', SHIPPED']
264265

265266
If you want to make sure that you cover all cases in a case stament, you can use the exhaustive case matcher: `Ruby::Enum::Case`. It will raise an error if a case/enum value is not handled, or if a value is specified that's not part of the enum. This is inspired by the [Rust Pattern Syntax](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html). If multiple cases match, all matches are being executed. The return value is the value from the matched case, or an array of return values if multiple cases matched.
266267

267-
> NOTE: This will add checks at runtime which might lead to slightly worse performance.
268+
> NOTE: This will add checks at runtime which might lead to worse performance. See [benchmarks](#benchmarks).
268269
269270
> NOTE: `:else` is a reserved keyword if you want to use `Ruby::Enum::Case`.
270271
@@ -299,6 +300,14 @@ Color.Case(color, {
299300
})
300301
```
301302

303+
## Benchmarks
304+
305+
Benchmark scripts are defined in the [`benchmarks`](benchmarks) folder and can be run with Rake:
306+
307+
```console
308+
rake benchmarks:case
309+
```
310+
302311
## Contributing
303312

304313
You're encouraged to contribute to ruby-enum. See [CONTRIBUTING](CONTRIBUTING.md) for details.

Rakefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@ require 'rubocop/rake_task'
1616
RuboCop::RakeTask.new(:rubocop)
1717

1818
task default: %i[rubocop spec]
19+
20+
namespace :benchmark do
21+
desc 'Run benchmark for the Ruby::Enum::Case'
22+
task :case do
23+
require_relative 'benchmarks/case'
24+
end
25+
end

benchmarks/case.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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+
# Test enum
10+
class Color
11+
include Ruby::Enum
12+
include Ruby::Enum::Case
13+
14+
define :RED, :red
15+
define :GREEN, :green
16+
define :BLUE, :blue
17+
end
18+
19+
puts 'Running 1.000.000 normal case statements'
20+
case_statement_time = Benchmark.realtime do
21+
1_000_000.times do
22+
case Color::RED
23+
when Color::RED, Color::GREEN
24+
'red or green'
25+
when Color::BLUE
26+
'blue'
27+
end
28+
end
29+
end
30+
31+
puts 'Running 1.000.000 ruby-enum case statements'
32+
ruby_enum_time = Benchmark.realtime do
33+
1_000_000.times do
34+
Color.case(Color::RED,
35+
{
36+
[Color::RED, Color::GREEN] => -> { 'red or green' },
37+
Color::BLUE => -> { 'blue' }
38+
})
39+
end
40+
end
41+
42+
puts "ruby-enum case: #{ruby_enum_time.round(4)}"
43+
puts "case statement: #{case_statement_time.round(4)}"
44+
45+
puts "ruby-enum case is #{(ruby_enum_time / case_statement_time).round(2)} times slower"

0 commit comments

Comments
 (0)