Erlang/Elixir string performance - can this be improved?

Hey @jola! Really enjoyed your talk. Learned a lot from it :slight_smile:

I jacked @JEG2’s code and wrote it in a slightly different way. For whatever reason it seems to run slightly faster for me (by like half a second or so). Maybe someone smarter than me knows the reason :wink: It uses await_many, which was introduced in Elixir 1.11. Nothing like resurrecting a thread for some code golf!

table = :ets.new(:words, [:public, write_concurrency: true])
pattern = :binary.compile_pattern([" ", "\n"])

for _ <- 1..System.schedulers_online() do
  Task.async(fn ->
    Stream.take_while(IO.binstream(:stdio, :line), fn line ->
      line
      |> String.split(pattern)
      |> Enum.each(fn word ->
        :ets.update_counter(table, word, {2, 1}, {word, 0})
      end)
    end)
    |> Stream.run()
  end)
end
|> Task.await_many(:infinity)

:ets.tab2list(table)
|> Enum.sort(fn {_, a}, {_, b} -> b < a end)
|> Enum.map(fn {word, count} ->
  [String.pad_leading(Integer.to_string(count), 8), " ", word, "\n"]
end)
|> IO.binwrite()
2 Likes