【问题标题】:Which of the following two pieces of code is faster or the same, and why?以下两段代码中哪一段更快或相同,为什么?
【发布时间】:2022-01-26 09:45:31
【问题描述】:

-记录(测试,{a = 10})。

test(Test) when is_record(Test,test) -> something.

test(#test{} = Test) -> 一些东西。

哪个更快或相同?为什么。

【问题讨论】:

    标签: performance erlang


    【解决方案1】:

    也许是第二个。运行时没有记录的概念,只有元组。

    21> rd(test, {a = 10}).               
    test
    22> erlang:is_record({test, 1}, test).
    true
    

    【讨论】:

      【解决方案2】:

      使用编译器进行测试并不难。 为此,我编写了这个模块……

      -module my_mod.
      -export [t1/1, t2/1].
      
      -record(test, {a = 10}).
      
      t1(Test) when is_record(Test,test) -> somethings.
      
      t2(#test{} = _Test) -> somethings.
      

      然后,我运行erlc -E my_mod.erl,这是生成的扩展代码:

      -file("my_mod.erl", 1).
      
      -module(my_mod).
      
      -export([t1/1,t2/1]).
      
      -record(test,{a = 10}).
      
      t1({test, _} = Test) when true ->
          somethings.
      
      t2({test, _} = _Test) ->
          somethings.
      

      所以,基本上……是一样的。使用 is_record(Test, test) 会增加一个无用的防护 (true),但这在 速度 方面应该不会产生影响。

      此外,如果您使用erlc -S my_mod.erl 来生成程序集列表,您会得到:

      {module, my_mod}.  %% version = 0
      
      {exports, [{module_info,0},{module_info,1},{t1,1},{t2,1}]}.
      
      {attributes, []}.
      
      {labels, 9}.
      
      
      {function, t1, 1, 2}.
        {label,1}.
          {line,[{location,"my_mod.erl",6}]}.
          {func_info,{atom,my_mod},{atom,t1},1}.
        {label,2}.
          {test,is_tagged_tuple,{f,1},[{x,0},2,{atom,test}]}.
          {move,{atom,somethings},{x,0}}.
          return.
      
      
      {function, t2, 1, 4}.
        {label,3}.
          {line,[{location,"my_mod.erl",8}]}.
          {func_info,{atom,my_mod},{atom,t2},1}.
        {label,4}.
          {test,is_tagged_tuple,{f,3},[{x,0},2,{atom,test}]}.
          {move,{atom,somethings},{x,0}}.
          return.
      
      
      {function, module_info, 0, 6}.
        {label,5}.
          {line,[]}.
          {func_info,{atom,my_mod},{atom,module_info},0}.
        {label,6}.
          {move,{atom,my_mod},{x,0}}.
          {line,[]}.
          {call_ext_only,1,{extfunc,erlang,get_module_info,1}}.
      
      
      {function, module_info, 1, 8}.
        {label,7}.
          {line,[]}.
          {func_info,{atom,my_mod},{atom,module_info},1}.
        {label,8}.
          {move,{x,0},{x,1}}.
          {move,{atom,my_mod},{x,0}}.
          {line,[]}.
          {call_ext_only,2,{extfunc,erlang,get_module_info,2}}.
      

      如您所见,这两个函数实际上是相同的:

      {function, …, 1, …}.
        {label,…}.
          {line,[{location,"my_mod.erl",…}]}.
          {func_info,{atom,my_mod},{atom,…},1}.
        {label,…}.
          {test,is_tagged_tuple,{f,…},[{x,0},2,{atom,test}]}.
          {move,{atom,somethings},{x,0}}.
          return.
      

      【讨论】:

      • 非常感谢您的回答,解决了我的问题
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 2021-02-16
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      相关资源
      最近更新 更多