Elixir 类型规范对生成的代码有影响吗?

Elixir 类型规范对生成的代码有影响吗?,elixir,Elixir,我正在根据99个问题列表做一些练习。对于P01,其目的是查找列表的最后一个元素,我的实现几乎总是优于list.last/1。差异约为20%,但执行之间的差异很大(有时超过100%)。测试是在一个新重启的VM上完成的,在一个包含一百万个元素的列表中,函数被称为10、100和1000 这是我的实现: def p01([]), do: nil def p01([h]), do: h def p01([_ | r]), do: p01(r) 仔细查看列表。最后一个/1源代码显示了两个区别 编译器指令@

我正在根据99个问题列表做一些练习。对于P01,其目的是查找列表的最后一个元素,我的实现几乎总是优于
list.last/1
。差异约为20%,但执行之间的差异很大(有时超过100%)。测试是在一个新重启的VM上完成的,在一个包含一百万个元素的列表中,函数被称为10、100和1000

这是我的实现:

def p01([]), do: nil
def p01([h]), do: h
def p01([_ | r]), do: p01(r)
仔细查看
列表。最后一个/1
源代码显示了两个区别

  • 编译器指令
    @compile:inline_list_funcs
    ,据我所知,它是一个仅应用于当前模块的Erlang指令。我不确定它是否对我的短代码有真正的影响
  • 类型规范
    @spec last([elem])::nil | elem当elem:var
  • 这两个更改使我的实现的执行时间更接近
    List.last/1

    Q1:编译器是否使用
    @spec..
    以某种方式优化代码


    Q2:附带问题:在我的测试中,erlang标准库函数
    :List.last/1
    总是比
    List.last/1
    好。同样,两次运行之间存在一些变化,但差异相当稳定。为什么
    List.last/1
    不是Erlang实现的简单包装器?

    我不确定问题2,但关于elixir文档中的问题1:“编译器从不使用类型规范来优化或修改代码”,请参阅:

    fwiw
    列表的官方代码。最后/1
    在这里,我很确定
    @spec
    不会改变codegen。如果只进行第一次更改(@compile),性能如何?Re:为什么不使用包装器,可能是因为
    lists:last
    List时对空列表抛出错误。last
    返回
    nil