Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 数组中的F#负指数_Arrays_Dictionary_F# - Fatal编程技术网

Arrays 数组中的F#负指数

Arrays 数组中的F#负指数,arrays,dictionary,f#,Arrays,Dictionary,F#,在我的应用程序中,需要预先计算并保留某些特定角度参数的三角函数值,范围从-90度到180度不等。 我可以创建数组(每个正弦、cos等一个),它将在第0个索引上存储-90角度的值,在检索时,我可以从索引中减去90 但是如果我们想使用[-90..180],在F#中有没有其他方法来指定索引的范围 这样我就可以有更有意义的实现 考虑替代解决方案,字典的使用速度是否与简单2D数组的使用速度一样快。可以使用一些索引算法: let inline idx i = (i + 270) % 270 因为它是内联的

在我的应用程序中,需要预先计算并保留某些特定角度参数的三角函数值,范围从-90度到180度不等。 我可以创建数组(每个正弦、cos等一个),它将在第0个索引上存储-90角度的值,在检索时,我可以从索引中减去90

但是如果我们想使用[-90..180],在F#中有没有其他方法来指定索引的范围 这样我就可以有更有意义的实现


考虑替代解决方案,字典的使用速度是否与简单2D数组的使用速度一样快。

可以使用一些索引算法:

let inline idx i = (i + 270) % 270

因为它是内联的,所以开销非常非常小。您只需使用myArray.[idx-90]。(你可能需要写不同的模值,但你明白了)

如果我很理解你的问题,你需要通过键/索引检索预先计算的值,键/索引是一个从-90到180的给定角度。像这样的

let value = precomputed.[-90]
您可以使用
Map
来实现这一点。F#映射实现为不可变AVL树,这是一种形成自平衡二叉树的高效数据结构。如果您有一个预计算的数据,并且需要频繁地按键查找,那么这将非常有效。在这种情况下,它的不可更改性确保了静态数据不会被误取修改,并且对性能有轻微影响,因为一旦初始化,您就不需要对其进行变异。但是,如果您需要经常修改它,我建议您使用常规的.NET字典,因为它们基于哈希表,比AVL树具有更好的性能

您可以将列表转换为地图,其中关键点为角度,值为预计算值:

let precomputedValus f =
    [for i in -90..180 ->
            i, f(i)]
            |> Map.ofList
其中
f
是进行预计算的函数。所以你可以得到每个角度的预计算地图

let sinValues = precomputedValus (fun e -> sin (float e))
您可以像这样访问程序计算的sin值

> sinValues.[-90];;
val it : float = -0.8939966636

最简单的方法是简单地生成一个函数,该函数在给定某个
i
的情况下返回一个预先计算的值
sini

let array_table = 
  let a = Array.init 271 (fun i -> sin <| float (i-90))
  fun i -> a.[i+90]
当我运行此命令时,
array\u table
大约比
no\u table
快8倍,比
map\u table
快22倍:

> fsharpi --optimize+ memo.fsx 
map_table
Real: 00:00:02.922, CPU: 00:00:02.924, GC gen0: 4, gen1: 0
no_table
Real: 00:00:01.091, CPU: 00:00:01.091, GC gen0: 3, gen1: 0
array_table
Real: 00:00:00.130, CPU: 00:00:00.130, GC gen0: 3, gen1: 0

您的问题是定义一个从-90到180的范围,或者按键提取,比如
let value=precomputed.[-90]
yes我想提取给定角度的预计算值。让value=precomputed.[-90]通常(包括
)可用于创建自定义索引器。但是如果程序的性能受到如此严格的限制,我不确定它们的开销。您确定标准三角函数是性能瓶颈吗?速度真的是问题吗?您是否在硬件上运行这些功能比较慢?我正在处理一个大规模的问题,由于严格的性能要求,我希望避免任何类型的处理延迟,这就是为什么我不想在运行时计算这些值,而是将它们存储在一个数组中,这样检索速度会非常快。我真的怀疑存储sin表是否会比计算快——计算速度非常快,您正在承受相当严重的缓存命中。请注意,在默认情况下,这将在小于-270的输入上失败
%
操作员。(对于一个给定的用例来说,这可能是好的,也可能不是好的)值是不可变的,所以我认为不需要字典。我发现你给出的解决方案非常合适,谢谢…现在我想通过这个我可以比较性能并得出一些结论。是的,map将非常适合。问题要求以度为单位输入
sin
接受弧度输入。另外,请注意,在典型的x86机器和应用程序上,这比直接计算慢一倍。(我刚刚做了一个粗略的测试运行,预计算导致速度大幅下降,低于原始速度的40%。当然,这可能取决于硬件、缓存、输入顺序的分支预测等)您可以使用任何需要的函数,而不是sin。这只是一个示例。在真实场景中评测应用程序时,应明确检查性能优化。这取决于实际计算函数的成本。所提到的问题与其说是性能问题,不如说是对问题的惯用看法,但这一点不应忽略。
> fsharpi --optimize+ memo.fsx 
map_table
Real: 00:00:02.922, CPU: 00:00:02.924, GC gen0: 4, gen1: 0
no_table
Real: 00:00:01.091, CPU: 00:00:01.091, GC gen0: 3, gen1: 0
array_table
Real: 00:00:00.130, CPU: 00:00:00.130, GC gen0: 3, gen1: 0