2

我有历史股票数据的大数据文件,我想通过 C# GUI 加载这些文件,然后在 F# 中使用不同的算法进行处理。随着时间的推移,附加值会附加到列表中。

列表是二维的,形式为

[[id, Open,High,Low,Close], [id, Open,High,Low,Close], ...]

F# 代码位于库中,无法使用 C# 列表(我无法在 F# 中获取列表第二维的值)。每次发生 F# 操作时都转换整个列表,成本太高。这些值也不能存储在 F# 列表中,因为 C# 无法处理它们。

建议的解决方案是:

  1. 要么将 F# 列表存储在 C# 中,仅出于存储目的,因为库无法存储值,以及包含相同值的 C# 列表,并根据需要转换列表的一部分。这里的主要问题是文件的大小可能是数 GB。

  2. 直接从 F# 中的文件读取所需的值并将计算值保存在其他文件中。这里的问题是文件的有效组织,以便可以快速选择要加载的行(例如,用于移动平均计算)。

4

2 回答 2

3

内部序列是否需要是一个列表?如果它总是具有相同的元素(OHLC),最好使用元组(或自定义类型),因为它明确了它的固定性质。我可能会做这样的事情:

module Stock =
  let (!) s = DateTime.Parse(s)

  let getOHLC() : unit -> seq<DateTime * float * float * float * float> =
    seq [
      !"18-Dec-12",27.25,27.63,27.14,27.56
      !"17-Dec-12",26.79,27.22,26.68,27.10
      !"14-Dec-12",27.11,27.13,26.70,26.81
      //...
    ]

如果你真的需要每个元素都是一个列表,你可以通过Seq.map seq.

seq函数定义为:

let seq (x:seq<'T>) = x

所以它只会向上转换,而不是复制。

于 2012-12-19T15:17:49.453 回答
1

每次发生 F# 操作时都转换整个列表,成本太高。

你量过吗?

这些值也不能存储在 F# 列表中,因为 C# 无法处理它们。

您应该能够从 C# 枚举 F# 列表的元素,因为它只是另一个可枚举的。

C# 中的类型System.Generics.List<System.Generics.List<Double>>被传递IEnumerable给 F#。不是调用OfSeq()转换列表值,而是强迫我遍历整个列表,调用OfSeq()每个元素,从而复制它。

调用类似的东西Array.ofSeq会创建一个新集合,但您不需要这样做来迭代内容。

请注意,您提供的类型的 F# 名称是ResizeArray<ResizeArray<float>>.

例如,您可以这样做:

let f (xss: ResizeArray<ResizeArray<float>>) =
  for xs in xss do
    for x in xs do
      printfn "%A" x

无需复制即可使用 F# 中的数据。

于 2012-12-22T23:31:14.117 回答