Skip to content

Instantly share code, notes, and snippets.

@ms-ati
Created August 10, 2017 19:51
Show Gist options
  • Select an option

  • Save ms-ati/331f0df61462966e02784d05798bbbe0 to your computer and use it in GitHub Desktop.

Select an option

Save ms-ati/331f0df61462966e02784d05798bbbe0 to your computer and use it in GitHub Desktop.

Revisions

  1. ms-ati created this gist Aug 10, 2017.
    60 changes: 60 additions & 0 deletions ruby_fast_case_when_set.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,60 @@
    # frozen_string_literal: true

    #
    # What's the fast way to find a constant set of values in a ruby case statement?
    #
    require "benchmark/ips"
    require "set"

    # Provides a `===` operator for a Set
    class SetCaseEq
    def initialize(enum)
    @set = enum.to_set
    end

    def ===(val)
    @set.include?(val)
    end
    end

    NUM = 1_000
    ARR = Array.new(NUM) { rand(1..100) }.freeze
    SET = SetCaseEq.new(ARR)

    def slow
    ARR.map do |n|
    case n
    when 1
    "a"
    when 42
    "b"
    when *ARR
    "c"
    else
    nil
    end
    end
    end

    def fast
    ARR.map do |n|
    case n
    when 1
    "a"
    when 42
    "b"
    when SET
    "c"
    else
    nil
    end
    end
    end

    raise "doesn't work" if slow != fast

    Benchmark.ips do |x|
    x.report("Array splat") { slow }
    x.report("Set#include?") { fast }
    x.compare!
    end
    13 changes: 13 additions & 0 deletions ruby_fast_case_when_set_results.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    ```
    $ ruby ruby_fast_case_when_set.rb
    Warming up --------------------------------------
    Array splat 21.000 i/100ms
    Set#include? 425.000 i/100ms
    Calculating -------------------------------------
    Array splat 226.534 (± 5.3%) i/s - 1.134k in 5.019588s
    Set#include? 4.282k (± 0.9%) i/s - 21.675k in 5.062326s
    Comparison:
    Set#include?: 4282.0 i/s
    Array splat: 226.5 i/s - 18.90x slower
    ```