Localtime_to_universaltime concurrent efficiency is slow - can it be improved?

It is found that the concurrency efficiency of localtime_to_universaltime is slow on the linux test. The test results are as follows:

Blockquote
12> utTc:tm(10000, 500, erlang, localtime_to_universaltime, [erlang:localtime()]).
=====================
execute erlang:localtime_to_universaltime({{2024,2,21},{8,26,27}}).
execute LoopTime:500
execute ProcCnts:10000
PMaxTime: 2955215390(ns) 2.96(s)
PMinTime: 649853(ns) 0.0(s)
PSumTime: 7394016430247(ns) 7394.02(s)
PAvgTime: 739401643.02(ns) 0.74(s)
FAvgTime: 1478803.29(ns) 0.0(s)
PGrar : 3236(cn) 0.32(%)
PLess : 6764(cn) 0.68(%)
=====================
ok
13> utTc:tm(10000, 500, erlang, universaltime_to_localtime, [erlang:localtime()]).
=====================
execute erlang:universaltime_to_localtime({{2024,2,21},{8,27,3}}).
execute LoopTime:500
execute ProcCnts:10000
PMaxTime: 20450604(ns) 0.02(s)
PMinTime: 597255(ns) 0.0(s)
PSumTime: 44342637286(ns) 44.34(s)
PAvgTime: 4434263.73(ns) 0.0(s)
FAvgTime: 8868.53(ns) 0.0(s)
PGrar : 5667(cn) 0.57(%)
PLess : 4333(cn) 0.43(%)
=====================
ok
14> utTc:tm(10000, 500, erlang, universaltime_to_posixtime, [erlang:localtime()]).
=====================
execute erlang:universaltime_to_posixtime({{2024,2,21},{8,27,23}}).
execute LoopTime:500
execute ProcCnts:10000
PMaxTime: 468431(ns) 0.0(s)
PMinTime: 27947(ns) 0.0(s)
PSumTime: 291129962(ns) 0.29(s)
PAvgTime: 29113.0(ns) 0.0(s)
FAvgTime: 58.23(ns) 0.0(s)
PGrar : 2147(cn) 0.21(%)
PLess : 7853(cn) 0.79(%)
=====================
ok
15> utTc:ts(5000000, erlang, localtime_to_universaltime, [erlang:localtime()]).
=====================
execute erlang:localtime_to_universaltime({{2024,2,21},{8,27,39}}).
execute LoopTime:5000000
MaxTime: 519878(ns) 0.0(s)
MinTime: 1224(ns) 0.0(s)
SumTime: 6474134064(ns) 6.47(s)
AvgTime: 1294.83(ns) 0.0(s)
Grar : 482051(cn) 0.10(%)
Less : 4517949(cn) 0.90(%)
=====================
ok
16> utTc:ts(5000000, erlang, universaltime_to_localtime, [erlang:localtime()]).
=====================
execute erlang:universaltime_to_localtime({{2024,2,21},{8,28,32}}).
execute LoopTime:5000000
MaxTime: 30597793(ns) 0.03(s)
MinTime: 1162(ns) 0.0(s)
SumTime: 6213025380(ns) 6.21(s)
AvgTime: 1242.61(ns) 0.0(s)
Grar : 163391(cn) 0.03(%)
Less : 4836609(cn) 0.97(%)
=====================
ok
17> utTc:ts(5000000, erlang, universaltime_to_posixtime, [erlang:localtime()]).
=====================
execute erlang:universaltime_to_posixtime({{2024,2,21},{8,28,59}}).
execute LoopTime:5000000
MaxTime: 23191(ns) 0.0(s)
MinTime: 49(ns) 0.0(s)
SumTime: 267652351(ns) 0.27(s)
AvgTime: 53.53(ns) 0.0(s)
Grar : 729399(cn) 0.15(%)
Less : 4270601(cn) 0.85(%)
=====================

Blockquote

the test mod utTc.erl utTc.erl

utTc:tm/5 is concurrent testing of multiple processes
utTc:ts/4 is single-process testing

Can the concurrent performance of this function be optimized?

ERTS just calls into the libc primitives, so if there is a bottleneck, it is in libc. I’ve not looked, but maybe there are better primitives for us to use that scale better.

Edit: The code that does the convertion is located here: otp/erts/emulator/beam/erl_time_sup.c at master · erlang/otp · GitHub

1 Like