我最近在 F# 中尝试了类似的东西。我从空格分隔文件中相关符号的 1 分钟条形格式开始,该文件有大约 80,000 个 1 分钟条形读数。从磁盘加载和解析的代码不到 1 毫秒。为文件中的每个周期计算 100 分钟 SMA 的代码是 530 毫秒。一旦在 1 毫秒内计算出来,我就可以从 SMA 序列中提取我想要的任何切片。我只是在学习 F#,所以可能有优化的方法。请注意,这是在多次测试运行之后,所以它已经在 Windows 缓存中,但即使从磁盘加载它也不会增加超过 15 毫秒的负载。
日期,时间,打开,高,低,关闭,卷 01/03/2011,08:00:00,94.38,94.38,93.66,93.66,3800
为了减少重新计算时间,我将整个计算的指标序列保存到磁盘中的单个文件中,并带有 \n 分隔符,并且在 Windows 文件缓存中加载和解析通常需要不到 0.5 毫秒。对完整时间序列数据进行简单迭代,以在 3 毫秒以下的操作中返回日期范围内的记录集,全年 1 分钟的条形图。我还将每日柱形图保存在一个单独的文件中,由于数据量较低,加载速度更快。
我使用 .net4 System.Runtime.Caching 层来缓存预先计算的系列的序列化表示,并使用几个专用于缓存的 RAM,我获得了几乎 100% 的缓存命中率,因此我可以访问任何预先计算的指标为任何符号设置通常在 1 毫秒以下运行。
从指标中提取我想要的任何数据片段通常不到 1 毫秒,因此高级查询根本没有意义。使用这种策略,我可以在不到 20 毫秒的时间内轻松加载 10 年的 1 分钟柱。
// Parse a \n delimited file into RAM then
// then split each line on space to into a
// array of tokens. Return the entire array
// as string[][]
let readSpaceDelimFile fname =
System.IO.File.ReadAllLines(fname)
|> Array.map (fun line -> line.Split [|' '|])
// Based on a two dimensional array
// pull out a single column for bar
// close and convert every value
// for every row to a float
// and return the array of floats.
let GetArrClose(tarr : string[][]) =
[| for aLine in tarr do
//printfn "aLine=%A" aLine
let closep = float(aLine.[5])
yield closep
|]