gpt4 book ai didi

erlang - 在 Erlang 中实现高效的二分查找

转载 作者:行者123 更新时间:2023-12-04 23:54:35 24 4
gpt4 key购买 nike

附言这是我第一次进入 SO,如果我做错了什么,请告诉我,我会尽力修复它。我花了几乎一整天的时间来修复这个算法实现,但我已经束手无策了!

我目前正在上的一门课是要求用 3 种截然不同的语言实现相同的二进制搜索算法的 3 种实现。对于其中一个,我决定硬着头皮去试试 Erlang。这是我的代码:

-export(main/1).

main(_) ->
io:format("Running trials... ~n", []),
N = [2 bsl (2 * X + 6) || X <- lists:seq(0, 7)],
lists:foreach(fun(X) -> io:format("~p: ~p ~n", [X, time_search(X)]) end, N).

time_search(Size) ->
A = list_to_tuple(create_list(Size)),
Iterations = 2000000,
time_search(A, Size + 1, 0, Iterations) / Iterations.

time_search(_, _, Sum, 0) -> Sum;
time_search(A, Key, Sum, IterationNum) ->
Before = now(),
bin_search(A, Key),
time_search(A, Key, Sum + timer:now_diff(now(), Before), IterationNum - 1).

create_list(Size) -> lists:seq(1, Size).

bin_search(A, Key) -> bin_search(A, Key, 1, tuple_size(A)).

bin_search(_, _, Lower, Upper) when Lower > Upper -> false;
bin_search(A, Key, Lower, Upper) ->
Mid = (Upper + Lower) div 2,
Item = element(Mid, A),
if
Key > Item -> bin_search(A, Key, Mid + 1, Upper);
Key < Item -> bin_search(A, Key, Lower, Mid - 1);
true -> true
end.

所以这是输出:
128: 250.8094435 µs
512: 308.7264845 µs
2048: 368.5770285 µs
8192: 425.748134 µs
32768: 477.6267655 µs
131072: 533.340876 µs
524288: 601.023178 µs
2097152: 661.099404 µs

但是与我的 ruby​​ 实现相比,它显然与 O(lg n) 相差了几个数量级

编辑:好的,所以也许不是命令......它看起来很对数,但它似乎仍然是错误的......

ruby :
128: 10.4756 µs
512: 11.8172 µs
2048: 13.5328 µs
8192: 15.3139 µs
32768: 17.0915 µs
131072: 18.8721 µs
524288: 21.5237 µs
2097152: 21.7187 µs

以前我使用列表,但我了解到那些没有 O(1) 检索时间,所以我切换到元组。是什么导致我的 Erlang 运行效率如此低下?

以防万一,这是我的 Ruby 实现
def p5_BinarySearch
n = Array.new(8){ |i| 2 << (2 * i + 6) }
n.each { |x|
time = timeSearch x
puts "#{x}: #{time.round 4} µs"
}
end

def timeSearch(size)
values = createArray size
iterations = 2e7.to_int
totalTime = 0
iterations.times{
before = Time.now
binarySearch(values, size + 1)
totalTime += Time.now - before
}
totalTime * 1e7 / iterations
end

def createArray(size)
(1..size).to_a
end

def binarySearch(values, key, low = 0, high = values.length - 1)
return false if low > high
mid = (low + high) / 2
return binarySearch(values, key, mid + 1, high) if key > values[mid]
return binarySearch(values, key, low, mid - 1) if key < values[mid]
true
end

if __FILE__ == $0
puts "Running trials..."
p5_BinarySearch
end

最佳答案

算法看起来不错,但在这种情况下使用 escript 解释器是问题所在。
使用 escript -c 运行 escript 以便在运行之前编译脚本而不是解释脚本,或者您可以按照 rvirding 的建议创建 Erlang 模块。有了这个,你可以看到它执行得非常快。

最好使用 os:timestamp() 而不是使用 now()以获得准确的时序值。更好的准确性是使用 timer:tc 功能。

{Time,_} = timer:tc(fun bin_search/2, [A, Key]),
time_search(A, Key, Sum + Time, IterationNum - 1).

结果在我的机器上是这样的。 (没有 -c 大约需要 450 微秒)
128: 1.105
512: 1.2005
2048: 1.4015
8192: 1.5145
32768: 1.7225
131072: 1.8515
524288: 2.024
2097152: 2.188

关于erlang - 在 Erlang 中实现高效的二分查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18854230/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com