Using tools such as telemetry in a performant manner requires access to 
some sort of low cost timing primitive to be able to calculate intervals. 
The community seems to use a mixture of `System.system_time/0` and/or 
`System.monotinic_time/0` to accomplish this, though neither of these are 
built specifically for purpose, and neither are terribly performant on 
super hot paths [1].

As it turns out, Erlang provides a tool for exactly this purpose, though 
Elixir doesn't expose it natively. That tool is `:os.perf_counter/1`:
 https://www.erlang.org/doc/man/os.html#perf_counter-1

It would be good to have first-class access to this in Elixir. Therefore, 
it is proposed to add the following to System:

* Add `System.perf_counter/0` & `System.perf_counter/1` as thin wrappers 
around `:os.perf_counter`, in the same manner as is currently done for 
`System.system_time` et al

* Add support for `perf_counter` to `System.convert_time_unit/3`. This is 
already supported in the underlying `:erlang.convert_time_unit/3`, it's 
just a matter of adding a clause to the private `normalize_time_unit` 
function.

Combined, these will allow for *significantly* faster interval calculation, 
which should help speed up all sorts of hot telemetry paths.

In practice, `perf_counter` is about twice as fast as `system_time`. A 
quick comparison (run on an M1 MacBook Air running 1.14/OTP 25.1):

```
Mix.install([{:benchee, "~> 1.0", only: :dev}])

Benchee.run(%{
  system_time: &System.system_time/0,
  monotonic_time: &System.monotonic_time/0,
  perf_counter: &:os.perf_counter/0
})

Name                     ips        average  deviation         median       
  99th %
perf_counter         54.03 M       18.51 ns   ±439.35%       18.33 ns       
20.01 ns
monotonic_time       28.10 M       35.58 ns  ±2758.64%       33.30 ns       
41.70 ns
system_time          23.44 M       42.67 ns  ±8964.02%       37.50 ns       
45.90 ns

Comparison:
perf_counter         54.03 M
monotonic_time       28.10 M - 1.92x slower +17.08 ns
system_time          23.44 M - 2.31x slower +24.16 ns
```

If folks are onboard I can get this implemented immediately.

m.

[1] https://github.com/mtrudel/thousand_island/issues/1, among others

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/9d4111e5-4799-4781-bbf1-43dae14dcb94n%40googlegroups.com.

Reply via email to