簡體   English   中英

是否推薦使用函數式編程(F#)的時間序列實現?

[英]Is Time Series implementation using functional programming (F#) recommended?

我正在開發一個.NET項目,其中一部分我將操縱時間序列。

由於項目的主要部分已在C#中實現,因此我描繪了一個繼承自SortedDictionary<DateTime,T>的面向對象設計。

然而,在過去的幾年里,我一直愛着函數式編程,我認為由於這個組件將受到相當狂野和強烈的算法的影響,我願意並行處理它,我很樂意擁有不可變結構。

我想用F#設計它,使用如下定義類型:

type TimeSeries<'t> = (DateTime * 't) seq

並繼續下去。

它具有不可變的優點,並且使用F#的Async模塊並行執行將非常簡單。 我還可以使用F#的度量單位功能。

我有點害怕不得不在C#中使用計算結果,我想知道是否已經嘗試過的人可以在實踐中給我一些關於結果的反饋。

最后是否易於使用,還是從C#切換到F#太復雜了?

當時間序列變大時,集合是不可變的效率問題嗎?

當我嘗試划分元素時,我是否可以保持類型通用,或者我是否必須使用我的函數快速切換到TimeSeries<float>

如果我想在某些功能的時間序列上使用基於C#的算法,這會使整個想法變得無用嗎?

您是否參考過有關時間序列功能實現效率的研究?

它具有不可變的優點,並且使用F#的異步模塊並行執行將非常簡單。

相反, seq很慢並且本質上是連續的。 SortedDictionary的字面F#等價物是Map但它不支持並行性。 Async模塊適用於異步並發編程,但對並行性有害。

假設您希望按時間快速搜索並按順序迭代但不是增量插入/刪除,那么您需要一個KeyValuePair<DateTime, 'T>的排序數組,因為這提供了出色的局部性,因此,並行算法的緩存復雜性。 請注意,如果您避免變異,那么數組可以是純函數。 請注意,F#2不會在DateTime鍵入specialize操作(如比較),因此您需要手動調用它們。

慣用的純功能等價物是由時間划分的平衡搜索樹:

type TimeSeries<'a> =
  | Leaf of DateTime * 'a
  | Branch of TimeSeries<'a> * DateTime * TimeSeries<'a>

這允許優雅的“並行”功能。 然而,實際情況是純函數式編程對於多核並行性並不好,因為它無法提供有關局部性的任何保證,因此,純函數式算法的高速緩存復雜性是不可預測的,性能通常很差。

當時間序列變大時,集合是不可變的效率問題嗎?

完全取決於你想用它做什么。

您是否參考過有關時間序列功能實現效率的研究?

您還沒有說過您打算實施的算法,甚至您想要快速執行的操作,因此很難以有用的方式討論測量的性能。 在我的上網本上運行快速基准測試,在字典中插入1,000,000個綁定,表明可變的SortedDictionary需要5.2s,而不可變的Map需要11.8s,因此存在顯着但不是很大的差異。 構建等效數組只需0.027秒。 迭代然后分別需要0.38s,0.20s和0.01s。

我有點害怕不得不在C#中使用計算結果,我想知道是否已經嘗試過的人可以在實踐中給我一些關於結果的反饋。

只需從F#代碼中公開一個標准的.NET接口,這很簡單。

有些要點需要注意:

  • 如果要將F#組件API公開給C#(或其他CLR語言),則應在F#組件的公共API中使用BCL(或OO類型)。 否則,您需要了解F#核心庫用於實現F#的功能感的所有類型。 例如: FsharFunc
  • 對於不可變數據結構的並行處理(只讀)很好,因為您確定沒有人會從后台修改數據,因此您不需要進行鎖定等。
  • 當你想讓一個項目附加到一個列表的末尾時,不可變數據結構“可能”聽起來不太好,理論上在不可變數據的情況下,它會將整個列表與新項目一起復制。 這通常是通過一些不可變數據結構的智能實現來避免的,例如clojure Persistent數據結構 ,而F#中沒有這種結構

我希望以上幾點可以幫助您確定最適合您具體實施的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM