Performance Erlang:不变变量在大小写表达式或参数列表中分配模式

Performance Erlang:不变变量在大小写表达式或参数列表中分配模式,performance,erlang,Performance,Erlang,对于以下情况: case SomeTuple of {} -> doing1(); {A,B,C,D,E,F} -> doing2_1(A), doing2_2({A,B,C,D,E,F}); _ -> doing3() end. 我更喜欢这样写: case SomeTuple of {} -> doing1(); X = {A,_,_,_,_,_}

对于以下情况:

case SomeTuple of
    {} ->
        doing1();
    {A,B,C,D,E,F} ->
        doing2_1(A),
        doing2_2({A,B,C,D,E,F});
    _ ->
        doing3()
end.
我更喜欢这样写:

case SomeTuple of
    {} ->
        doing1();
    X = {A,_,_,_,_,_} ->
        doing2_1(A),
        doing2_2(X);
    _ ->
        doing3()
end.
问题:

  • 第二种情况是否会消耗额外的内存或其他资源
  • 建议采用哪种方法

  • @浩贤,唯一的选择是第二种情况<代码>执行2_2({A,,,,,,,,})是禁止的,此代码不会编译。在erlang中,变量
    \uu
    没有赋值,它只是告诉编译器它应该匹配任何erlang术语
    {A,{u,{u,{u,{u,}=T
    只是验证
    T
    是由6个元素组成的元组,并将其第一个元素分配给
    A

    它不同于使用语法
    \u Var
    。在这种情况下,
    \u Var
    是可以使用的真实变量(即使不建议使用)。此符号指示编译器,如果函数稍后未使用此变量,则不要发出警告。此符号通常用于函数、接收或case子句,以提醒未使用术语的含义:

    receive
       {test, _From, Msg} -> io:format("receive test message ~p~n",[Msg]);
       {read, From} -> From ! afunction()
    end,
    
    我在一些模式匹配中也看到了这种符号,比如
    {A,\T,\u T}=function()
    ,它验证函数是否返回一个3元素元组,其中第二个和第三个元素相等,并将第一个元素分配给
    A
    。请注意,在这种情况下,使用
    T
    而不是
    \u T
    不会引起警告,但读者更清楚的是,以后不会使用
    \u T

    [编辑]

    编译器进行了大量优化,开发梁机的团队负责节省时间和内存,因此您不应该首先考虑性能和优化

    编写应用程序时,最重要的一点是将其划分到具有适当职责的适当流程中

    在我看来,坚持OTP原则也很重要:这将允许您使用许多有用的工具来调试、跟踪、调整。。。你的申请。其他人也更容易理解它

    当然,就像在任何语言中一样,编写代码以使其他人最容易阅读


    如果你发现两个代码变体之间的差异很重要,我想这意味着你的应用程序遇到了真正的麻烦,或者你试图用错误的工具解决问题。

    第二个版本是唯一合法的版本,也是表达问题的一种非常正常的方式。更正常的做法是完全避免使用case语句(如果可能的话),并在函数头中执行此类操作,即使这意味着将这些行拆分为一个小的辅助函数(这使您有机会有意义地命名case match表示的过程,并改进代码的语义)

    几乎没有一种情况下,你应该有一个像
    {}
    这样的“nuple”。我想不出有什么理由会发生这种情况——在非Erlang库中,元组的语义用途可能不被识别,这可能会有些奇怪。(如果我得到了,我会认为它是坏数据,让它故意崩溃。) 至于表现

    变量在Erlang中绑定的时间尽可能晚,实际上“绑定”是一种轻量级的操作,比其他不起作用的动态类型语言所期望的要轻(即使这个想法是灵活的,因为有时只传递一个引用)。在绑定过程中,你唯一浪费周期的时候就是当你输出大量你永远不会使用的无意义的中间变量时——这就是为什么编译器会对未使用的变量发出警告的原因

    不过,在这种情况下,你不会得到毫无意义的中间产物:

    foo(Data) ->
        {ok, Value} = somefun(Data),
        otherfun(Value).
    
    {ok,Value}
    位经常被新手视为“浪费”的赋值,因为它不能在长函数组合中直接传递。他们缺少的是这是一个值断言,而不仅仅是一个赋值。许多函数都会返回这样一个断言友好的元组(例如,从外部资源读取、键值查找等),这些函数要么是副作用的,要么可能会搜索但找不到某些东西。这些都非常重要,可以让您在开始使用坏数据做疯狂的事情(这是对周期的真正浪费!)之前尽早崩溃流程

    无论如何,这是一个担心性能的错误地方。元组匹配在Erlang中非常快,并且记录在编译时被简化为元组,因此它们完全等价。仅仅将参数传递给函数并不需要传递或复制消息


    在你有一个可测量的工作系统之前,不要考虑性能。假设一个大规模并发系统的性能就像猜测一场风暴将产生多少个特定大小的波浪一样有意义——在你有机会测量之前,你根本不知道。Erlang中的任何东西都是可跟踪的,因此将性能调整留待以后进行总是明智的。Erlang对开发后跟踪、评测和调优非常友好,它使您的时间远比处理器的时间重要。明智地利用您的时间,首先编写一个漂亮的代码库,然后使用您期望的任何负载进行测试。我曾经有过很少的案例,在这些案例中,我编写了惯用的Erlang代码(也就是说,没有在一个god进程中承担太多的责任),实际上遇到了性能瓶颈,而这些瓶颈不是网络、磁盘访问或其他外部资源。

    第一个案例是非法的。第二种情况将发出警告:a未使用,如果您真的调用与默认情况下相同的函数,{}子句将无效。@Pascal我已经更新了问题,您有什么想法吗???我更喜欢第二种情况,因为它侧重于“有趣的”赋值。@Steve,您为什么删除编辑过的文本?不管怎么说,我之前的评论现在是无用的,因为