是否推荐使用函数式编程(F#)的时间序列实现?

SRK*_*RKX 5 .net f# functional-programming

我正在开发一个.NET项目,其中一部分我将操纵时间序列.

由于项目的主要部分已经在C#中实现,我已经描绘了一个继承自的面向对象设计SortedDictionary<DateTime,T>.

然而,在过去的几年里,我一直爱着函数式编程,我认为由于这个组件将受到相当狂野和强烈的算法的影响,我愿意并行处理它,我很乐意拥有不可变结构.

我想用F#设计它,使用如下定义类型:

type TimeSeries<'t> = (DateTime * 't) seq
Run Code Online (Sandbox Code Playgroud)

并继续下去.

它具有不可变的优点,并且使用F#Async模块并行执行将非常简单.我也可以使用F#的度量单位功能.

我有点害怕不得不在C#中使用计算结果,我想知道是否已经尝试过的人可以在实践中给我一些关于结果的反馈.

最后是否易于使用,还是从C#切换到F#太复杂了?

当时间序列变大时,集合是不可变的效率问题吗?

当我尝试划分元素时,我是否可以保持类型通用,或者我是否必须TimeSeries<float>快速切换到我的函数?

如果我想在某些功能的时间序列上使用基于C#的算法,这会使整个想法变得无用吗?

您是否参考过有关时间序列功能实现效率的研究?

Jon*_*rop 8

它具有不可变的优点,并且使用F#的异步模块并行执行将非常简单.

相反,它seq是缓慢而固有的连续性.字面F#等同的SortedDictionaryMap,但它具有并行性的支持.该Async模块适用于异步并发编程,但对并行性不利.

假设您希望按时间快速搜索并按顺序迭代但不是增量插入/删除,那么您需要一个排序数组,KeyValuePair<DateTime, 'T>因为这提供了出色的局部性,因此,并行算法的缓存复杂性.请注意,如果您避免变异,那么数组可以是纯粹的功能.请注意,F#2不会输入specialize操作(比如比较),DateTime因此您需要手动调用它们.

惯用的纯功能等价物是由时间划分的平衡搜索树:

type TimeSeries<'a> =
  | Leaf of DateTime * 'a
  | Branch of TimeSeries<'a> * DateTime * TimeSeries<'a>
Run Code Online (Sandbox Code Playgroud)

这允许优雅的"并行"功能.然而,实际情况是纯函数式编程对于多核并行性并不好,因为它无法提供有关局部性的任何保证,因此,纯函数式算法的高速缓存复杂性是不可预测的,性能通常很差.

当时间序列变大时,集合是不可变的效率问题吗?

完全取决于你想用它做什么.

您是否参考过有关时间序列功能实现效率的研究?

您还没有说过您打算实施的算法,甚至您想要快速执行的操作,因此很难以有用的方式讨论测量的性能.在我的上网本上运行快速基准测试,在字典中插入1,000,000个绑定,表明mutable SortedDictionary需要5.2s,而immutable Map需要11.8s,因此存在显着但不是很大的差异.构建等效数组只需0.027秒.迭代然后分别需要0.38s,0.20s和0.01s.

我有点害怕不得不在C#中使用计算结果,我想知道是否已经尝试过的人可以在实践中给我一些关于结果的反馈.

只需从F#代码中公开一个标准的.NET接口,这很简单.