erlang:now/0 is faster than os:timestamp/0?

2019-08-08 17:44发布

问题:

As said in manual, http://www.erlang.org/erldoc?q=erlang:now

If you do not need the return value to be unique and monotonically increasing, use os:timestamp/0 instead to avoid some overhead.

os:timestamp/0 should be faster than erlang:now/0

But I tested on my PC with timer:tc/3, for 10000000 calls, time spent in microsecond is:

erlang:now 951000
os:timestamp 1365000

Why erlang:now/0 faster than os:timestamp/0?

My OS: Windows 7 x64, erlang version: R16B01.

------------------edit-----------------

I wrote another test code in parallel (100 thread), os:timestamp/0 performed better in parallel. here are data:

----- single thread ------
erlang:now 95000
os:timestamp 147000

----- multi thread ------
erlang:now 333000
os:timestamp 91000

So, I think the "overhead" is for parallel.

回答1:

I've always thought that the 'some overhead' comment was darkly amusing. The way erlang:now/0 achieves its trick of providing guaranteed unique, monotonically increasing values is to take out a per-VM global lock. In a serial test you won't notice anything, but when you've got a lot of parallel code running, you may.

The function os:timestamp/0 doesn't take out a lock and may return the same value in two processes.



回答2:

This was recently discussed on the erlang-questions mailing list ("erlang:now() vs os:timestamp()" on 3rd April 2013), where two interesting results emerged:

  • erlang:now seems to be faster than os:timestamp in interpreted code (as opposed to compiled code, where os:timestamp is faster).
  • If you benchmark them, you should measure the time taken using os:timestamp instead of erlang:now, since erlang:now forces the clock to advance.


回答3:

Apart from the excellent answer by troutwine, the reason why erlang:now() is faster in a serial test is probably that it avoids the kernel since you may be calling it faster than time progresses and then you are in a situation where you don't hit the kernel as often.

But note, that your test is deceiving until you add more than a single core. Then os:timestamp() like troutwine writes, will outperform erlang:now().

Also note you are on a weak platform, namely Windows. This usually affects performance in non-trivial ways.



标签: erlang