当前位置 : 主页 > 网络安全 > 测试自动化 >

性能 – 为什么Elixir消息传递时间与消息大小成正比?

来源:互联网 收集:自由互联 发布时间:2021-06-22
我发现在Elixir中传递消息所花费的时间与消息的大小成正比,而我预计它会相对恒定.由于数据结构是不可变的,因此运行时应该能够通过引用(在恒定时间内)在进程之间传递大型结构.考虑
我发现在Elixir中传递消息所花费的时间与消息的大小成正比,而我预计它会相对恒定.由于数据结构是不可变的,因此运行时应该能够通过引用(在恒定时间内)在进程之间传递大型结构.考虑以下测试.

use Bitwise

defmodule PerfTask do
  def pack(s) do
    {millis, packed} = :timer.tc(fn -> Enum.to_list(s) end)
    IO.puts("packed in #{millis} millis")
    Task.async(fn -> packed end)    
  end

  def unpack(t) do
    {millis, unpacked} = :timer.tc(fn -> Task.await(t) end)
    IO.puts("unpacked in #{millis} millis")
    unpacked
  end

  def go(n) do
    IO.puts "n = #{n}"
    1..n |> pack |> unpack
  end
end

PerfTask.go(1 <<< 20)

在列表中有2 ^ 20个元素,打印出来

n = 1048576
packed in 106481 millis
unpacked in 9916 millis

构建列表所需的时间大约是将其从Task中取出的10倍. (请注意,列表是在任务启动之前构建的.所有任务都要返回已经构建的列表.)

在列表中有2 ^ 22个元素,它会打印出来

n = 4194304
packed in 397428 millis
unpacked in 38748 millis

比例仍然约为10:1.长4倍的列表在进程之间发送的时间长达4倍.我错过了什么?

$iex
Erlang/OTP 18 [erts-7.2] [source] [64-bit] [smp:8:8] [async-threads:10] [kernel-poll:false]

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

(我已经确认问题不是特定于Task模块,而是将其替换为具有类似结果的普通进程.)

根据@rvirding的这个 answer你的基本假设是有缺陷的.引用维尔丁先生:

. . . current versions of Erlang basically copy everything except for
larger binaries. In older pre-SMP times it was feasible to not copy
but pass references. While this resulted in very fast message passing
it created other problems in the implementation, primarily it made
garbage collection more difficult and complicated implementation. I
think that today passing references and having shared data could
result in excessive locking and synchronisation which is, of course,
not a Good Thing.

在Elixir的上下文中,“较大的二进制文件”意味着非常长的字符串 – 大于64K.

网友评论