每天写个程序, 第二天

时间:2022-05-21 19:52:08

今天写个suan好了, 不是大蒜的suan, 是算盘的算. 有个人一直和我争, erlang里面record和map哪个更好. 我语重心长,循循善诱: "就用map啦, 多方便, record是什么鬼, 不就是tuple吗". 那人还不服: "record速度比map快多了, map辣鸡". 那我今天就来算一下, 看谁打脸.

刚接到一个神秘电话: "我大Keyword才是坠吼的", 所以 Keyword 选手临时加入.

round 1

有请三位选手出场!:

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字)"

请裁判说明比赛规则!:

  ...

@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)

请三位选手进入赛道, 各就各位!:

  ...

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

裁判准备发令!:

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

"预备!噼里啪啦砰!":

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 取消.