Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Elixirで関数の実行速度を測定する

More than 1 year has passed since last update.

(この記事は、「fukuoka.ex x ザキ研 Advent Calendar 2017」の22日目です)

昨日は@piacere_exさんの「関数型でデータサイエンス#4:インプットしたデータを集約する②」でした.


はじめに

 前回の記事「Elixirで2次元のリスト加算関数をつくる」では,2次元リストの加算関数について説明しました。

  • ガード句とパターンマッチングは併用できる
  • 2次元リストだと表示が上手くいかないことがあるので注意

今回の記事は打って変わり,再帰呼び出しによるリストの操作以外にも,EnumFlowで記述したコードの実行速度を測定した結果を示します.

実行速度測定

 実行速度の測定には:timer.tcを使います.以下は与えられた関数の処理時間を単位[s]で表示するコードです.

こちらの記事(Elixirでパフォーマンス測定)を参考にさせていただきました.

defmodule Test
 ...
  # サンプルコード
  def timed(func) do
      func
      |> :timer.tc
      |> elem(0) 
      |> Kernel./(1000000)
  end
  ...
end

 
上記のコードに少し手を加えて,強引に実行速度を測定します.
Flowのコードはこちらの記事(Elixir Flowでlazyな並列分散処理)を参考にさせていただきました.

defmodule Test
    def timed_recursive() do
    :timer.tc( fn -> 
      1..10_000_000 
      |> Enum.to_list 
      |> Numex.twice end )
      |> elem(0) 
      |> Kernel./(1_000_000)
  end

  def timed_enum() do
    :timer.tc( fn -> 
      1..10_000_000 
      |> Enum.to_list 
      |> Enum.map(& &1 * 2 ) end )
      |> elem(0) 
      |> Kernel./(1_000_000)
  end

  def timed_flow(stage) do
    :timer.tc(fn -> 
    1..10_000_000 
    |> Flow.from_enumerable(stages: stage) 
    |> Flow.map(& &1 * 2) 
    |> Enum.to_list
    |> Enum.sort end) 
    |> elem(0) 
    |> Kernel./(1_000_000)
  end

  # 要素ごと2倍
  def twice([a|tla]) when not is_list(a) do
    [a*2|twice( tla)] 
  end
  def twice([]), do: [] 
end

確認

使用したデータは,(A) 一千万もしくは,(B) 一億の要素をもつリストです.

実行速度[s] (A)10_000_000 (B)100_000_000
Recursive 1.0722782 27.61662
Enum 1.2500004 17.484315
Flow(1) 3.5802442 41.678115
Flow(2) 6.6561348 123.548497

※一千万の方の結果は10回実行した平均値,一億の方は1回実行した結果です.

処理自体が単純なものなので,Flowで並列化させても効果は薄そうです.(並列化するコストの方が高そう)
Enumと比較してみると,(A)のときは,いい勝負になってますが,(B)のときは最適化もされていない再帰呼び出しでは及ばなさそうです.

最後に

今回は実行速度を測定しました.再帰呼び出しが最速とも言い切れない,まとまりのない情報でしたが,実行速度を測ってみたいという方の参考になれば幸いです.

参考文献

明日は @Takeshi-Kogu さんの「モジュールをファイルに書き込んでみる(後半)」です。お楽しみに!

hisaway
CAD/CAMを開発する会社の学生活用アルバイトにて,形状処理を行うソフトウェアの開発(C++/C#).大学の研究の一環でElixir, Rustを勉強していました。Phoenix勉強中。
fukuokaex
エンジニア/企業向けにElixirプロダクト開発・SI案件開発を支援する福岡のコミュニティ
https://fukuokaex.fun/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away