我一直在寻找一种使用.NET进行适当的算法编码的方法,并具有现代语言的所有优点(例如,我喜欢强大的类型检查,运算符重载,lambda,通用算法)。通常,我用C++编写算法(主要是图像处理)。因为F#作为一种语言似乎很有趣,所以我玩了一点,但它似乎非常慢。作为最简单的测试,我只是做了一些数组操作->图像的亮度增加:
let r1 = rgbPixels |> Array.map (fun x -> x + byte(10) )
这似乎比C++实现的速度至少慢了8倍-对于更复杂的算法(例如2D卷积。
有什么更快的方法还是我会错过任何特定的编译器设置(是的,使用优化版本来构建发行版...)?
我愿意为此付出高昂的代价,但这样的开销并不好(我需要并行使用8个内核来补偿:))-至少它破坏了进一步学习的动力...我的另一个选择将把我较重的算法留在C++中并与托管的C++进行接口(interface),但这不是很好,因为维护托管包装器将是一个负担。
最佳答案
如果您担心性能,那么要记住的重要事情之一就是F#默认情况下不会改变任何东西。这需要复制许多简单的算法实现,例如您所描述的。
编辑:我不知道为什么,但是下面的代码的简单测试提供了劣于Array.map
的结果。执行这些类型的优化时,请确保概要介绍您尝试的任何算法。但是,我在for
和map
之间得到了非常相似的结果。Array.map
为操作的结果创建一个新数组,而不是Array.iteri
。
rgbPixels |> Array.iteri (fun i x -> rgbPixels.[i] <- x + 10uy)
请注意,这可以包装在您自己的模块中,如下所示
module ArrayM =
let map f a = a |> Array.iteri (fun i x -> a.[i] <- f x)
不幸的是,这是一个必要的邪恶,因为函数式编程的主要承租者之一就是在算法允许的范围内尽可能多地坚持不变的对象,然后一旦完成,就转向对性能至关重要的突变。如果您一开始就知道自己的绩效至关重要,那么您将需要从这类帮助者入手。
另请注意,可能有一个提供此功能的库,我只是不了解而已。