从循环内的大量数据中检查属性的有效方法

时间:2016-08-09 22:48:07

标签: performance optimization ocaml branch-prediction

请考虑这段通用代码:

for j = 0 to (Array.length myArray) - 1 do
    if property.(id) then
        (* do a bunch of stuff*)
done

这里,property是一个非常大的布尔数组。 在这个实验中,我们有2个案例:

  • 在第1天,property.(id)始终是 true

  • 在第二个中,property.(id)可以是 true false

我们希望第二种情况获胜,因为它会跳过代码执行。 但由于分支调节,这不会发生。 我们还尝试过分割property而不是if语句,但第一种情况仍然胜出。 (这些都是OCaml社区成员的建议)。

我们的问题定义是:我们可以检测一个允许我们跳过部分代码的属性。但是使用一个大的布尔数组来保存哪个元素具有此属性会使得对属性本身的检查比保存的代码执行更慢。

因此,现在的问题更为笼统:实施此问题的更好方法是什么?

我们非常感谢社区的任何建议。

2 个答案:

答案 0 :(得分:0)

在我看来,您的问题有两种可能的解决方案:

  • 如果您仍想使用for循环,那么我建议使用exception来退出for循环

    exception YourExn of something
    
    try
      for j = 0 to (Array.length property) - 1 do
        if property.(id) then
          (* do a bunch of stuff*)
        else raise (YourExn result)
      done
    with YourExn res -> (* do something *)
    

    异常YourExn of something

  • 另一种解决方案是编写递归函数而不是使用for循环。我建议使用这个解决方案,因为使用递归函数是函数式编程的一种标准。

    let rec traverse property id =
      if id > (Array.length property) then
        (* exit *)
      else if property.(id) then
        (* do a bunch of stuff*)
        traverse property (id + 1)
      else
        (* exit *) in
    
    traverse property 0
    

答案 1 :(得分:0)

在这里阅读了类似的问题Why is it faster to process a sorted array than an unsorted array?后,我的代码的最佳解决方案是编写无分支条件,如那样可以做什么?的答案。< / p>