LoginSignup
5
3

Supervisor経由で25万プロセス起動する負荷を現代PC+Elixir 1.14.4/OTP25で試す

Last updated at Posted at 2023-12-31

この記事は、Elixir Advent Calendar 2023 シリーズ12 の22日目です


【本コラムは、5分で読めます】 ※各ライブラリをお試しいただく場合は各自次第で

piacere です、ご覧いただいてありがとございます :bow:

下記コラムで行っている「Supervisor経由で10万プロセス起動する負荷」を現代PC+最新Elixirで試すシリーズです

実施PC/Elixir/OTP

  • PC
    • CPU:i9-9900K 3.60GHz
    • メモリ:64 GByte
Erlang/OTP 25 [erts-13.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.14.4) - press Ctrl+C to exit (type h() ENTER for help)

ソースコード

import Supervisor.Spec

defmodule PassSupervisor do
	def start_link( processes ) do
		start = Timex.now()
		servers = 1..processes |> Enum.map( &( worker( PassGenServer, [], id: &1 ) ) )
		Supervisor.start_link( servers, strategy: :one_for_one )
		IO.puts( "Spent Milliseconds=#{Timex.diff( Timex.now(), start, :milliseconds )}" )
	end

	def cat( parameter, name \\ "0" ) do
		GenServer.call( :global.whereis_name( name ), { :cat, parameter } )
	end

	def pwd( name \\ "0" ) do
		GenServer.call( :global.whereis_name( name ), :pwd )
	end
end

defmodule PassGenServer do
	use GenServer

	def start_link() do
		{ :ok, pid } = GenServer.start_link( __MODULE__, "" )
		#IO.puts( "--- PassGenServer.start_link() PID=#{inspect pid} ---" )
		{ :ok, pid }
	end

	def handle_call( :pwd, _from, _state ) do
		{ :ok, result } = File.cwd()
		{ :reply, result, "" }
	end

	def handle_call( { :cat, path }, _from, _state ) do
		{ :ok, result } = File.read( path )
		{ :reply, result, "" }
	end
end

実施結果

10万プロセス生成に、Elixir 1.15.0/OTP25や、Elixir 1.16.0/OTP26より、少し重くなりました

iex> PassSupervisor.start_link(100000)
Spent Milliseconds=782
:ok

限界確認

25万プロセスは明確に遅くなっています

iex> PassSupervisor.start_link(250000)
Spent Milliseconds=2039
:ok
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3