Open deadtrickster opened 7 years ago
So there is no big speed difference, and in theory dincs can be removed entirely. OTOH doubles are finite on both ERTS and C sides while int counters currently not. And we going NIF-way inc can be implemented with fetch_and_add.
However:
CAS loop can be very long - we can block scheduler.
Current NIF benchmark doesn't perform counter resolving - this has to be done as ETS lookup
with possible optimization (like Benoit does) - provide with
wrapper and store resource in process-dict.
Also on lookups - first metric use looks now like this:
inc -> badarg -> insert_metric, Next call: just inc (ets:update_counter)
first call when using nif:
inc -> no_resource -> create_resource -> insert to ets -> increment
Next call -> ets:lookup -> increment.
And with replaces ets:lookup with get and adds put to the first call.
Since dirty nifs are experimental I need to limit number of cas iterations and add loop inside incr_counter on erlang side to allow context switching
Now for handling doubles prometheus.erl uses gen_server (because there is no ets:update_counter for doubles). This PR intended to provide nif based alternative for gen_server.
Benchmark for ets:update_counter-based counter:
Results for dinc (without call_timeout adjusted):
Results for double + atomic_compare_exchange_strong
cc @benoitc