Julia while 循环比 for 循环慢?

Julia while loop slower than for loop?

提问人:WNed 提问时间:12/6/2022 更新时间:12/6/2022 访问量:229

问:

我正在使用 Julia 1.8.2 进行代码降临第 6 天,并注意到 while 和 for 循环之间存在一些奇怪的性能差异。

我编写了一个带有循环的实现,但意识到我不需要遍历每个索引,并且在某些情况下我可以跳过索引,但是当我使用循环重写代码时,运行时间是 ~10 倍。和 循环代码都给出了正确答案。 然后我添加了一个小的基本 vs 循环测试,看看它是我的代码还是实际的循环,结果更加戏剧化。测试花了 ~0.5 秒,而测试几乎立即完成。forwhileforwhilewhileforwhilefor

我的完整代码如下,有关数据,请参阅 AoC day6

我的问题是为什么循环这么慢?Julia 解释器是否由于某种原因难以优化循环?whilewhile

using BenchmarkTools

function parse_data()
    open(joinpath(dirname(@__FILE__), "data/day6.txt")) do f
        while !eof(f)
            line = readline(f)
            return line
        end
    end
end

function test_for(data)
    tot = 0
    for i = 1:length(data) * 100
        tot += 1
    end
    return tot
end

function test_while(data)
    tot = 0
    i = 1
    while i <= length(data) * 100
        tot += 1
        i += 1
    end
    return tot
end

function solve_problem_for(data)
    marker_length = 14
    for i = 1:length(data)
        repeat = false
        for (j, item) in enumerate(view(data, i:i+marker_length - 1))
            repeat = repeat || occursin(item, view(data, i + j:i + marker_length - 1))
            if repeat
                break
            end
        end
        if !repeat
            return i + marker_length - 1
        end
    end
end

function solve_problem_while(data)
    marker_length = 14
    i = 1
    while i <= length(data)
        repeat = false
        for (j, item) in enumerate(view(data, i:i+marker_length - 1))
            repeat = repeat || occursin(item, view(data, i + j:i + marker_length - 1))
            if repeat
                i += j - 1
                break
            end
        end
        if !repeat
            return i + marker_length - 1
        end
        i += 1
    end
end

function main()
    data = parse_data()
    @time sol = solve_problem_while(data)
    @time sol = solve_problem_while(data)
    println(sol)
    @time sol = test_while(data)
    @time sol = test_while(data)

    @time sol = solve_problem_for(data)
    @time sol = solve_problem_for(data)
    println(sol)
    @time sol = test_for(data)
    @time sol = test_for(data)
end


main()
性能 for-loop while-loop Julia

评论

4赞 Justinas 12/6/2022
在每次迭代中,您重新计算 .将其移出环路条件whilelength(data) * 100
1赞 Odilf 12/6/2022
如果你想准确地对某些东西进行基准测试,你应该使用并获得更好的结果BenchmarkTools@benchmark
5赞 DNF 12/6/2022
我得到相同的时间。请注意,无论输入数据的长度如何,两者都只需要几纳秒。这是因为编译器识别出此循环的输出是 N*(N+1)/2,并且只是跳过该循环。test_fortest_while
0赞 WNed 12/7/2022
@Justinas 谢谢,这次重新计算导致了速度变慢。编译器似乎没有意识到它在循环过程中不会改变。
0赞 Justinas 12/7/2022
@WNed 这是因为在每个循环中都检查了条件

答: 暂无答案