首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >F#代码优化还是真的那么慢?

F#代码优化还是真的那么慢?
EN

Stack Overflow用户
提问于 2012-02-08 04:47:56
回答 2查看 336关注 0票数 6

我一直在寻找一种方法来使用.NET进行适当的算法编码,同时具有现代语言的所有优点(例如,我喜欢强类型检查、运算符重载、lambda、泛型算法)。通常我用C++编写我的算法(主要是图像处理)。由于F#作为一种语言似乎很有趣,我玩了一点,但它似乎非常慢。作为一个最简单的测试,我只是做了一些数组操作,增加了图像的->亮度:

代码语言:javascript
运行
复制
let r1 = rgbPixels |> Array.map (fun x -> x + byte(10) )

它似乎比比较的C++实现慢至少8倍-对于更复杂的算法,如2D卷积,情况更糟。有没有更快的方法,或者我错过了任何特定的编译器设置(是的,构建带有优化的版本...)?我愿意为好的和高的抽象买单,但是这样的开销是不好的(我需要在8个内核上并行来补偿:) --至少它破坏了进一步学习的动力……我的另一个选择是将较重的算法留在C++中,并与管理的C++接口,但这并不好,因为维护托管包装器将是一个相当大的负担。

EN

回答 2

Stack Overflow用户

发布于 2012-02-08 05:02:08

如果您担心性能,那么需要记住的重要一点是,F#在默认情况下不会发生任何变化。这需要在许多简单的算法实现中进行复制,例如您描述的算法。

编辑:我不知道为什么,但是对以下代码的简单测试提供的结果不如Array.map。在执行这些类型的优化时,请确保分析您尝试的任何算法。然而,我在formap之间得到了非常相似的结果。

Array.map会为操作结果创建一个新数组,而您需要的是Array.iteri

代码语言:javascript
运行
复制
rgbPixels |> Array.iteri (fun i x -> rgbPixels.[i] <- x + 10uy)

请注意,这可以封装在您自己的模块中,如下所示

代码语言:javascript
运行
复制
module ArrayM =
    let map f a = a |> Array.iteri (fun i x -> a.[i] <- f x)

不幸的是,这是一个必要的错误,因为函数式编程的主要租用者之一是在算法允许的情况下尽可能地坚持不可变对象,然后一旦完成,在性能至关重要的地方更改为突变。如果你知道你的性能从一开始就很关键,你就需要从这些帮助器开始。

还要注意的是,可能有一个库提供了这种功能,我只是不知道它在手边。

票数 6
EN

Stack Overflow用户

发布于 2012-02-08 05:18:15

我认为可以肯定地说,对于数组操作,惯用的F#通常无法与优化的C++的性能相匹配,原因有几个:

将根据.NET中的数组边界检查

  1. 数组访问,以确保内存安全。CLR的JIT编译器能够省略一些常规代码的边界检查,但这通常需要您使用具有显式边界的for循环,而不是更惯用的constructs.
  2. There。与使用lambdas (例如fun i -> ...)等抽象相比,F#通常会有少量的开销。在紧密循环中,与在循环体中完成的工作相比,这个小的开销可能会非常重要。
  3. 据我所知,CLR JIT编译器没有像C++编译器那样充分利用SSE指令。

在账本的另一边,

  1. 你在F#代码中永远不会有缓冲区溢出。
  2. 你的代码将更容易推理。作为推论,对于给定级别的总代码复杂性,您通常可以在F#中实现比在C++中更复杂的算法。
  3. 如果需要,您可以编写运行速度更接近C++的通用代码,如果您发现需要编写C++来满足性能C++的要求,还可以与不安全的C++代码进行互操作
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9183646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档