【问题标题】:ocaml %identity functionocaml % 标识函数
【发布时间】:2015-12-31 19:46:24
【问题描述】:

我想知道为什么我们需要像“%identity”这样的函数,它和let a = a是一样的。使用它会不会提高性能?

我在我的程序中引入了幻像输入,多次调用标识函数来转换类型,很好奇“%identity”是否可以减少一些开销。

【问题讨论】:

    标签: types ocaml external


    【解决方案1】:

    %identity 函数是实现的一部分,而不是 OCaml 语言的一部分。它告诉编译器(本质上)无需将函数的参数更改为其返回值。换句话说,它告诉编译器继续使用相同的值,但改变其类型的想法。如果使用不当,它基本上会使 OCaml 类型系统的所有出色安全保证失效。此外,当然,它不能保证在该语言的任何其他实现中工作(包括 INRIA 编译器的未来版本)。

    OCaml 编译器的内联功能应该已经保证不会为标识函数生成任何代码。所以我建议你继续使用它们。

    更新

    在 cmets 中回答一个不相关的问题......假设你有函数组合和恒等函数:

    let (<<) f g x = f (g x)
    let id x = x
    

    然后是添加列表元素、相乘列表元素以及组合列表中所有函数的函数:

    # let sum l = List.fold_right (+) l 0;;
    val sum : int list -> int = <fun>
    # let product l = List.fold_right ( * ) l 1;;
    val product : int list -> int = <fun>
    # let composition l = List.fold_right (<<) l id;;
    val composition : ('a -> 'a) list -> 'a -> 'a = <fun>
    

    例子:

    # sum [2; 3; 5; 7];;
    - : int = 17
    # product [2; 4; 17];;
    - : int = 136
    # let mx = composition [(+) 1; ( * ) 10];;
    val mx : int -> int = <fun>
    # mx 2;;
    - : int = 21
    

    重点是0是加法,1是乘法,id是函数组合。 id 一直很有用,就像 0 和 1 一样。

    【讨论】:

    • 我们什么时候正常使用identity函数(不一定是%identity)?
    • 这有点像问我们何时使用数字 0 和 1。在函数是一等值的语言中,恒等函数非常有用。
    • 抱歉,我想我的问题应该是,请给我一个有用的案例,应该或必须使用 let f x = x 吗?
    • (我添加了一个更新。我认为这实际上应该是一个单独的问题。)
    【解决方案2】:

    使用 %identity 作为外部原语可以并且将减少与每次应用 (fun x -&gt; x) 闭包时评估相关的开销。

    OCaml 编译器对 % 原语进行特殊处理:bytecomp/translcore.ml 将每个原语与一个特殊的内置 AST 节点相关联(在 %identity 的情况下,它被映射到 Pidentity);编译器在节点上匹配并简化它所应用的表达式。在本机编译器的情况下,相关行是:

    • asmcomp/closure.ml 第 197 行和 ss.:简化 %identity 应用于参数本身的常量参数:

      begin match p with
        Pidentity -> make_const_int x
      | Pnegint -> make_const_int (-x)
      
    • asmcomp/cmmgen.ml 第 1047 行和 ss.:将 %identity 简化为应用程序的 LHS 以直接评估参数:

      match p with
        (* Generic operations *)
          Pidentity ->
            transl arg
      

    字节码编译器对原语有类似的简化规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-04
      • 2021-03-20
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多