3 ms·
> Would Erlang/Elixir do better? I don't know, but I wouldn't be so sure. Pretty sure it can. Let's give it a try: #!/usr/bin/env escript %%! +P 20000
by rdtsc 7y ago
> Would Erlang/Elixir do better? I don't know, but I wouldn't be so sure.
Pretty sure it can. Let's give it a try:
#!/usr/bin/env escript
%%! +P 2000000
%% run with ./spawn_n 1000000
-mode(compile).
main([NStr]) ->
N = list_to_integer(NStr),
T0 = erlang:system_time(millisecond),
Parent = self(),
Waiter = spawn(fun() -> Parent ! {final_result, wait(N, 0)} end),
spawn_n(N, Waiter),
Res = receive {final_result, R} -> R end,
Dt = erlang:system_time(millisecond) - T0,
io:format("Done in ~p sec result:~p~n", [Dt/1000.0, Res]),
ok.
wait(0, Acc) ->
Acc;
wait(N, Acc) ->
receive {result, R} -> ok end,
wait(N - 1, Acc + R).
spawn_n(0, _Waiter) ->
ok;
spawn_n(N, Waiter) ->
spawn(fun() -> Waiter ! {result, 1} end),
spawn_n(N - 1, Waiter).
And it outputs:
./spawn_n 1000000
Done in 1.613 sec result:1000000
In summary, it started 1M processes, all with isolated heaps, pre-emptable, with only a few KB of stack size. They didn't execute much just sent their result to a collector process and then exited. All in about 5x as fast as C++.
- norswap 7y agoA most excellent answer :)
- alexeiz 7y agoIf the C++ code in comparison uses boost.coroutine2 library, then it's not surprising it performs poorly. Boost.coroutine2 library has an architectural flaw which causes it to throw (and then catch) an exception on coroutine completion. https://github.com/boostorg/coroutine2/issues/25 https://github.com/boostorg/coroutine2/issues/25