[elixir! #0047] 簡單對比record, map, keyword

一篇舊文, 轉載於個人cnblog. 使用的erlang版本爲19數據結構

今天寫個suan好了, 不是大蒜的suan, 是算盤的算. 有我的一直和我爭, erlang裏面record和map哪一個更好. 我語重心長,循循善誘: "就用map啦, 多方便, record是什麼鬼, 不就是tuple嗎". 那人還不服: "record速度比map快多了, map辣雞". 那我今天就來算一下, 看誰打臉.ui

剛接到一個神祕電話: "我大Keyword纔是墜吼的", 因此 Keyword 選手臨時加入.code

round 1

有請三位選手出場!:blog

defmodule Suan.Record do
  require Record
  Record.defrecord :mr_rec, a: 0, b: 0, c: 0, d: 0
end

defmodule Suan.Bench do
  import Suan.Record
  @mr_map %{a: 0, b: 0, c: 0, d: 0}
  @mr_key [a: 0, b: 0, c: 0, d: 0]

  ...

請領導發言!(來自百度文庫):
"咳咳嗯哼呃~ 六月是春潮奔涌、繁花爭妍的季節,六月是釋放活力,飛揚激情的時節,在這美好的時刻,2017年首屆BEAM VM陽光體育運動會開幕了。在此,我謹表明 erlang/OTP 向本屆運動會的開幕表示熱烈的祝賀!向籌備本屆運動會的全體工做人員表示衷心的感謝!...(省略1000字)"io

請裁判說明比賽規則!:class

...

  @doc """
  每次操做爲數據結構裏的某一項加1, a,b,c,d 各操做一次.
  重複10000 次.
  """
  def round1(who), do: (fn -> do_round1(who) end) |> :timer.tc() |> IO.inspect(label: "#{who}")

  defp do_round1(:mr_rec), do: rec_update(mr_rec(), 0)
  defp do_round1(:mr_key), do: key_update(@mr_key, 0)
  defp do_round1(:mr_map), do: map_update(@mr_map, 0)

請三位選手進入賽道, 各就各位!:import

...

  defp rec_update(_rec, 10000), do: :ok
  defp rec_update(rec, n) do
    rec1 = rec |> update_a() |> update_b() |> update_c() |> update_d()
    rec_update(rec1, n+1)
  end
 
  defp update_a(rec=mr_rec(a: a)), do: mr_rec(rec, a: a+1)
  defp update_b(rec=mr_rec(b: b)), do: mr_rec(rec, b: b+1)
  defp update_c(rec=mr_rec(c: c)), do: mr_rec(rec, c: c+1)
  defp update_d(rec=mr_rec(d: d)), do: mr_rec(rec, d: d+1)

    
  defp map_update(_map, 10000), do: :ok
  defp map_update(map, n) do
    plus1 = fn x -> x+1 end
    map1  = map |> update_in([:a], plus1) |> update_in([:b], plus1) |> update_in([:c], plus1) |> update_in([:d], plus1)
    map_update(map1, n+1)
  end


  defp key_update(_key, 10000), do: :ok
  defp key_update(key, n) do
    kup! = fn x, i -> Keyword.update!(x, i, &(&1+1)) end
    key1 = key |> kup!.(:a) |> kup!.(:b) |> kup!.(:c) |> kup!.(:d)
    key_update(key1, n+1)
  end

end

裁判準備發令!:require

defmodule Suan do
  @moduledoc """
  Documentation for Suan.
  """
  import Suan.Bench, only: [round1: 1]

  def start do
    Enum.each [:mr_rec, :mr_map, :mr_key], &round1/1
  end
end

"預備!噼裏啪啦砰!":module

iex(1)> Suan.start
mr_rec: {3829, :ok}
mr_map: {16166, :ok}
mr_key: {10398, :ok}
:ok
iex(2)> Suan.start
mr_rec: {4318, :ok}
mr_map: {22036, :ok}
mr_key: {15962, :ok}
:ok
iex(3)> Suan.start
mr_rec: {4348, :ok}
mr_map: {23165, :ok}
mr_key: {15461, :ok}
:ok

宣佈比賽結果!:
record 遙遙領先, 得到冠軍, keyword第二, 用時是record的三倍, map選手墊底, 用時約爲record的四倍.百度

round 2

因不滿比賽結果, 裁判憤而離場, round 2 取消.

相關文章
相關標籤/搜索