gpt4 book ai didi

optimization - F# 自动泛化和性能

转载 作者:行者123 更新时间:2023-12-03 15:45:46 25 4
gpt4 key购买 nike

我最近遇到了意外的代码优化,想检查一下我对观察到的内容的解释是否正确。以下是该情况的一个非常简化的示例:

let demo =
let swap fst snd i =
if i = fst then snd else
if i = snd then fst else
i
[ for i in 1 .. 10000 -> swap 1 i i ]

let demo2 =
let swap (fst: int) snd i =
if i = fst then snd else
if i = snd then fst else
i
[ for i in 1 .. 10000 -> swap 1 i i ]

两个代码块之间的唯一区别是,在第二种情况下,我将 swap 的参数显式声明为整数。然而,当我使用#time 在 fsi 中运行 2 个片段时,我得到:

案例 1 真实:00:00:00.011,CPU:00:00:00.000,GC gen0:0,gen1:0,gen2:0
案例 2 真实:00:00:00.004,CPU:00:00:00.015,GC gen0:0,gen1:0,gen2:0

即第二个片段的运行速度是第一个片段的 3 倍。这里的绝对性能差异显然不是问题,但如果我大量使用交换功能,它就会堆积起来。

我的假设是性能下降的原因是,在第一种情况下,swap 是通用的并且“需要相等”,并检查 int 是否支持它,而第二种情况不需要检查任何东西。这是发生这种情况的原因,还是我错过了其他东西?更一般地说,我是否应该将自动泛化视为一把双刃剑,也就是说,一个很棒的功能可能会对性能产生意想不到的影响?

最佳答案

我认为这通常与问题 Why is this F# code so slow 中的情况相同。 .在那个问题中,性能问题是由要求 comparison 的约束引起的。在您的情况下,它是由 equality 引起的约束。

在这两种情况下,编译的通用代码都必须使用接口(interface)(和装箱),而专门的编译代码可以直接使用 IL 指令进行整数或浮点数的比较或相等。

避免性能问题的两种方法是:

  • 特化代码使用intfloat正如你所做的
  • 将函数标记为 inline以便编译器自动对其进行专门化

  • 对于较小的函数,第二种方法更好,因为它不会生成太多代码,并且您仍然可以以通用方式编写函数。如果您仅将函数用于单一类型(按设计),那么使用第一种方法可能是合适的。

    关于optimization - F# 自动泛化和性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10475079/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com