Hey @jola! Really enjoyed your talk. Learned a lot from it
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 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()