jdfrens
5/16/2015 - 3:31 AM

Elixir performance experiments with Enum and Stream and combinations.

defmodule SillyExperiment do

  def strip_and_reverse(s), do: s |> String.strip |> String.reverse

  def all_stream do
    File.stream!("/usr/share/dict/words")
    |> Stream.map(&strip_and_reverse/1)
    |> Stream.each(&IO.puts/1)
    |> Stream.run
  end

  def eager_map do
    File.stream!("/usr/share/dict/words")
    |> Enum.map(&strip_and_reverse/1)
    |> Stream.each(&IO.puts/1)
    |> Stream.run
  end

  def eager_puts do
    File.stream!("/usr/share/dict/words")
    |> Stream.map(&strip_and_reverse/1)
    |> Enum.each(&IO.puts/1)
    |> Enum.to_list
  end

  def all_eager do
    File.stream!("/usr/share/dict/words")
    |> Enum.map(&strip_and_reverse/1)
    |> Enum.each(&IO.puts/1)
  end

  def eager_first_20 do
    File.stream!("/usr/share/dict/words")
    |> Enum.map(&strip_and_reverse/1)
    |> Enum.take(20)
    |> Enum.each(&IO.puts/1)
  end

  def stream_first_20 do
    File.stream!("/usr/share/dict/words")
    |> Stream.map(&strip_and_reverse/1)
    |> Stream.take(20)
    |> Stream.each(&IO.puts/1)
    |> Stream.run
  end

end

[
  { "all_stream", &SillyExperiment.all_stream/0 },
  { "eager_map", &SillyExperiment.eager_map/0 },
  { "eager_puts", &SillyExperiment.eager_puts/0 },
  { "all_eager", &SillyExperiment.all_eager/0 },
  { "eager_first_20", &SillyExperiment.eager_first_20/0 },
  { "stream_first_20", &SillyExperiment.stream_first_20/0 }
]
|> Enum.map(fn ({ name, func }) -> { name, :timer.tc(func) } end)
|> Enum.each(fn { name, { time, _ } } -> :io.format("~s\t~10.3f\n", [name, time / 1_000_000]) end)