.net 是否建议使用函数式编程(F#)实现时间序列?
我正在.NET中开发一个项目,其中一部分我将处理时间序列 由于项目的主要部分是用C#实现的,因此我从.net 是否建议使用函数式编程(F#)实现时间序列?,.net,f#,functional-programming,.net,F#,Functional Programming,我正在.NET中开发一个项目,其中一部分我将处理时间序列 由于项目的主要部分是用C#实现的,因此我从SortedDictionary继承了面向对象的设计 然而,在过去的几年里,我一直喜欢函数式编程,我认为,由于这个组件将受到相当广泛和密集的算法的影响,我愿意并行处理它,并且我会喜欢拥有一个不变的结构 我考虑用F#设计它,使用如下定义类型: type TimeSeries<'t> = (DateTime * 't) seq type TimeSeries需要注意的几点: 如果要将F
SortedDictionary
继承了面向对象的设计
然而,在过去的几年里,我一直喜欢函数式编程,我认为,由于这个组件将受到相当广泛和密集的算法的影响,我愿意并行处理它,并且我会喜欢拥有一个不变的结构
我考虑用F#设计它,使用如下定义类型:
type TimeSeries<'t> = (DateTime * 't) seq
type TimeSeries需要注意的几点:
- 如果要将F#组件API公开给C#(或其他CLR语言),则应在F#组件的公共API中使用BCL(或OO类型)。否则,您需要了解F#核心库用于实现F#功能的所有类型。例如:
FsharFunc
- 不可变数据结构的并行处理(只读)很好,因为您确信没有人会在幕后修改数据,因此不需要执行锁定等操作
- 当您想将一个项附加到列表的末尾时,不可变的数据结构“可能”听起来不太好,理论上,在不可变数据的情况下,它会将整个列表与新项一起复制。这通常是通过一些不可变数据结构的智能实现来避免的,比如在
clojure
中,这在F#中是不存在的
我希望以上几点有助于您决定什么最适合您的具体实施
它具有不可变的优点,并且使用F#的异步模块并行执行将非常简单
相反,seq
速度慢且固有串行性。与SortedDictionary
相当的文本F#等价物是Map
,但它不支持并行性。Async
模块适合异步并发编程,但不适合并行
假设您需要按时间快速搜索并按顺序迭代,而不是增量插入/删除,那么您需要的是KeyValuePair的排序数组
这允许优雅的“并行”功能。然而,现实情况是,纯函数式编程不利于多核并行,因为它不能提供关于局部性的任何保证,因此,纯函数式算法的缓存复杂性是不可预测的,性能往往很差
当时间序列变大时,集合不可变这一事实不是一个效率问题吗
这完全取决于你想用它做什么
你有没有关于时间序列功能实现效率的研究的参考资料
你没有提到你打算实现的算法,甚至没有提到你想要快速的操作,所以很难用一种有用的方式来谈论衡量的性能。在我的上网本上运行一个快速基准测试,在字典中插入1000000个绑定,结果表明可变的SortedDictionary
需要5.2秒,而不可变的Map
需要11.8秒,所以有一个显著但不是很大的差异。构建等效阵列只需0.027秒。然后迭代分别需要0.38秒、0.20秒和0.01秒
我只是有点害怕不得不使用C#中的计算结果,我想知道已经尝试过的人是否可以在实践中给我一些关于结果的反馈
只要从F#代码中公开一个标准的.NET接口就很容易了。Jon,我认为timeseries的关键应用程序是计算运行统计数据(mean/std/etc)和运行窗口回归。建立时间并不那么重要。另一种情况是,它实时接收新数据,并保持固定的最大长度,就像循环缓冲区一样。@matlabdbuser:是的,完全正确。我最近也做了一个项目,主要是按顺序的大多数值,但偶尔的“修复”进来,旧的时间,放在某个数据中间。当然,这些不同情况下的最佳数据表示方式完全不同。因此,了解OP希望处理的是哪一个是至关重要的。嗨,你能更新一下这个问题吗?我有一个类似的问题,即决定哪种实现最好。我计划尽可能使用Iobervables“实时”更新。
type TimeSeries<'a> =
| Leaf of DateTime * 'a
| Branch of TimeSeries<'a> * DateTime * TimeSeries<'a>