Counting numbers performantly
:couters module
Determine counter size
# how many numbers to manage
counter_size = 2
# one-based numbering
autorace_index = 1
toukon_index = 2
Create a counter instance
-
options
-
:atomics (default)
-
write_concurrency
my_counter = :counters.new(counter_size, [:write_concurrency])
get_state = fn ->
%{
autorace: :counters.get(my_counter, autorace_index),
toukon: :counters.get(my_counter, toukon_index)
}
end
get_state.()
Add number to counter
:counters.add(my_counter, autorace_index, 1)
:counters.add(my_counter, toukon_index, 123)
get_state.()
Subtract number from counter
:counters.sub(my_counter, autorace_index, 124)
:counters.sub(my_counter, toukon_index, 24)
get_state.()
Overwrite counter
:counters.put(my_counter, autorace_index, 0)
:counters.put(my_counter, toukon_index, 0)
get_state.()
Count large mounts of numbers
do_count = fn _ ->
case Enum.random([:toukon, :autorace]) do
:toukon -> :counters.add(my_counter, toukon_index, 1)
:autorace -> :counters.add(my_counter, autorace_index, 1)
end
end
1..100_000
|> Task.async_stream(&do_count.(&1), max_concurrency: 500)
|> Stream.run()
get_state.()
Links