无点式的性能影响 [英] Performance Implications of Point-Free style

查看:118
本文介绍了无点式的性能影响的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习使用F#进行函数式编程的第一步,我刚刚遇到了前向管道(|>)和前向组合(>>)操作符。起初我以为他们只是糖而不是对最终的运行代码产生影响(尽管我知道管道帮助类型推理)。

文章:
函数式编程中point free风格的优缺点是什么?
这有两个有趣且信息丰富的答案(不是简化事物,而是为我打开了一堆围绕自由或毫无意义的风格)我从这些(和其他阅读)获得的回家是无点是一个辩论区域。像lambas一样,无点式可以使代码更容易理解,或者更难以使用,具体取决于使用情况。



但是我的问题涉及到对第一个答案的评论:
AshleyF在答案中默念:


在我看来,构成可以通过让编译器更加明显地意识到不需要像流水线中产生中间值那样来降低GC压力;

Gasche回复:
$ b帮助所谓的毁林问题更容易处理。 $ b


关于改进编译的部分根本不是真的。在大多数语言中,无点式会降低表演。 Haskell严重依赖优化,因为它是使这些东西的成本可以承受的唯一方法。充其量,这些组合器是内联的,你会得到一个等效的有意义的版本


任何人都可以扩展性能影响吗? (一般而言,特别是F#)我刚才认为这是一种书写式的东西,编译器会将这两个成语都放到等效的代码中。

div>

这个答案将会是F#特定的。我不知道其他函数式语言的内部是如何工作的,而且它们不能编译为CIL会产生很大的变化。



我可以看到三个问题在这里:


  1. 使用 |>

  2. 使用>> 的性能影响是什么?

  3. 声明一个函数与它的参数和没有它们之间的区别?

答案(使用您链接到的问题):


  1. 有没有 x |>之间的区别sqr |>总和总和(sqr x)



    不,没有。编译后的CIL完全一样(这里以C#表示):

      sum.Invoke(sqr.Invoke(x))

    使用Invoke(),因为 sqr sum 不是CIL方法,它们是 FSharpFunc , )

  2. c>和 sum(sqr x)



    不,这两个样本都编译为与上面相同的CIL。 / p>

  3. let sumsqr = sqr>> sum let sumsqr x =(sqr>> sum)x



    是的,编译的代码是不同的。如果指定参数,则将 sumsqr 编译为正常的CLI方法。但是如果你没有指定它,它将被编译为 FSharpFunc 类型的属性,并带有一个支持字段,它的 Invoke()方法包含了代码。



    但是所有的效果是,调用无点版本意味着加载一个字段( FSharpFunc ),如果指定了参数,则不会这样做。但我认为这不应该对性能产生明显影响,除非是在极端的情况下。

  4. I’m taking my first baby-steps in learning functional programing using F# and I’ve just come across the Forward Pipe (|>) and Forward Composition (>>) operators. At first I thought they were just sugar rather than having an effect on the final running code (though I know piping helps with type inference).

    However I came across this SO article: What are advantages and disadvantages of "point free" style in functional programming? Which has two interesting and informative answers (that instead of simplifying things for me opened a whole can of worms surrounding "point-free" or "pointless" style) My take-home from these (and other reading around) is that point-free is a debated area. Like lambas, point-free style can make code easier to understand, or much harder, depending on use. It can help in naming things meaningfully.

    But my question concerns a comment on the first answer: AshleyF muses in the answer:

    "It seems to me that composition may reduce GC pressure by making it more obvious to the compiler that there is no need to produce intermediate values as in pipelining; helping make the so-called "deforestation" problem more tractable."

    Gasche replies:

    "The part about improved compilation is not true at all. In most languages, point-free style will actually decrease performances. Haskell relies heavily on optimizations precisely because it's the only way to make the cost of these things bearable. At best, those combinators are inlined away and you get an equivalent pointful version"

    Can anyone expand on the performance implications? (In general and specifically for F#) I had just assumed it was a writing-style thing and the compiler would unstrangle both idioms into equivalent code.

    解决方案

    This answer is going to be F#-specific. I don't know how the internals of other functional languages work, and the fact that they don't compile to CIL could make a big difference.

    I can see three questions here:

    1. What are the performance implications of using |>?
    2. What are the performance implications of using >>?
    3. What is the performance difference between declaring a function with its arguments and without them?

    The answers (using examples from the question you linked to):

    1. Is there any difference between x |> sqr |> sum and sum (sqr x)?

      No, there isn't. The compiled CIL is exactly the same (here represented in C#):

      sum.Invoke(sqr.Invoke(x))
      

      (Invoke() is used, because sqr and sum are not CIL methods, they are FSharpFunc, but that's not relevant here.)

    2. Is there any difference between (sqr >> sum) x and sum (sqr x)?

      No, both samples compile to the same CIL as above.

    3. Is there any difference between let sumsqr = sqr >> sum and let sumsqr x = (sqr >> sum) x?

      Yes, the compiled code is different. If you specify the argument, sumsqr is compiled into a normal CLI method. But if you don't specify it, it's compiled as a property of type FSharpFunc with a backing field, whose Invoke() method contains the code.

      But the effect of all is that invoking the point-free version means loading one field (the FSharpFunc), which is not done if you specify the argument. But I think that shouldn't measurably affect performance, except in the most extreme circumstances.

    这篇关于无点式的性能影响的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆