Array.safe 和 unsafe_get/set 有什么区别
What's the difference between Array.safe and unsafe_get/set
我在 OCaml forum. I use a lot of Array.set
and Array.get
(this is most of my code 1 2) 上寻求一些建议来优化我的代码,有人告诉我我可以使用 Array.unsafe_get
和 Array.unsafe_set
来获得一些时间。
在此上下文中,safe
和 unsafe
函数有什么区别?
Array.get
和 Array.set
检查索引是否在数组的范围内。
例如,
[||].(2) 0
失败
Exception: Invalid_argument "index out of bounds".
不安全版本不执行此测试,因此
(Array.unsafe_get [||] 2) 0
因分段错误而失败。
在热循环中,绑定检查测试可能会减慢循环。
不安全版本不执行边界检查。因此,如果您访问超出数组边界的索引,您可能会遇到分段错误或更糟的情况,安全版本只会抛出异常。
如果您已经显式或隐式检查了边界(例如,在循环条件中检查它们),则只应使用不安全函数1,例如,2
(* here [i] is guaranteed to be in range by the loop condition,
so we can use the unsafe version to remove double check *)
let unsafe_init_array xs v =
for i = 0 to Array.length xs - 1 do
Array.unsafe_set xs i v
done
1)附带说明一下,我个人从未发现使用这些函数有任何显着的性能提升。我的猜测是,在现代超标量计算机中,推测执行能够并行加载数据和执行边界检查。所以,最终,他们不值得冒险。不过,在不太复杂的架构上可能会有所不同。和往常一样,YMMV,所以请对此持保留态度。
2) 这个循环的安全版本在我的机器上只慢了 6%,但是更安全也更容易阅读,
let safe_init_array xs v =
for i = 0 to Array.length xs - 1 do
xs.(i) <- v
done
我在 OCaml forum. I use a lot of Array.set
and Array.get
(this is most of my code 1 2) 上寻求一些建议来优化我的代码,有人告诉我我可以使用 Array.unsafe_get
和 Array.unsafe_set
来获得一些时间。
在此上下文中,safe
和 unsafe
函数有什么区别?
Array.get
和 Array.set
检查索引是否在数组的范围内。
例如,
[||].(2) 0
失败
Exception: Invalid_argument "index out of bounds".
不安全版本不执行此测试,因此
(Array.unsafe_get [||] 2) 0
因分段错误而失败。
在热循环中,绑定检查测试可能会减慢循环。
不安全版本不执行边界检查。因此,如果您访问超出数组边界的索引,您可能会遇到分段错误或更糟的情况,安全版本只会抛出异常。
如果您已经显式或隐式检查了边界(例如,在循环条件中检查它们),则只应使用不安全函数1,例如,2
(* here [i] is guaranteed to be in range by the loop condition,
so we can use the unsafe version to remove double check *)
let unsafe_init_array xs v =
for i = 0 to Array.length xs - 1 do
Array.unsafe_set xs i v
done
1)附带说明一下,我个人从未发现使用这些函数有任何显着的性能提升。我的猜测是,在现代超标量计算机中,推测执行能够并行加载数据和执行边界检查。所以,最终,他们不值得冒险。不过,在不太复杂的架构上可能会有所不同。和往常一样,YMMV,所以请对此持保留态度。
2) 这个循环的安全版本在我的机器上只慢了 6%,但是更安全也更容易阅读,
let safe_init_array xs v =
for i = 0 to Array.length xs - 1 do
xs.(i) <- v
done