朱莉娅的全局变量使代码变慢较慢

发布于 2025-02-13 17:41:54 字数 2473 浏览 1 评论 0原文

我有以下在大约8秒内运行的代码:

using Random

DEBUG = false
PRISONERS = 100
ATTEMPTS = 50
function tryit()
    a = [1:1:PRISONERS;]
    a = shuffle(a)
    for i in 1:PRISONERS
        if DEBUG
            println("prisoner $i")
        end
        count = 0
        check = i
        while count <= ATTEMPTS
            count += 1
            if a[check] == i
                if DEBUG
                    println("Attempt $count: Checking box $check and found my number")
                end
                break
            else
                if DEBUG
                    println("Attempt $count: Checking box $check and found $(a[check])")    
                end       
                check = a[check]               
            end
        end
           
        if count > ATTEMPTS
            if DEBUG
                println("Prisoner $i failed to find his number in 50 attempts")
            end
            return false
        end
    end
    return true
end

function main()
    tries = 100000
    success = 0.0
    for i in 1:tries
        if tryit()
            success += 1
        end
    end
    println("Ratio of success = $(success / tries)")
end

main()

将函数内部的全局变量移动将运行时间降低到第十:

using Random

function tryit()
    DEBUG = false
    PRISONERS = 100
    ATTEMPTS = 50
    a = [1:1:PRISONERS;]
    a = shuffle(a)
    for i in 1:PRISONERS
        if DEBUG
            println("prisoner $i")
        end
        count = 0
        check = i
        while count <= ATTEMPTS
            count += 1
            if a[check] == i
                if DEBUG
                    println("Attempt $count: Checking box $check and found my number")
                end
                break
            else
                if DEBUG
                    println("Attempt $count: Checking box $check and found $(a[check])")    
                end       
                check = a[check]               
            end
        end
           
        if count > ATTEMPTS
            if DEBUG
                println("Prisoner $i failed to find his number in 50 attempts")
            end
            return false
        end
    end
    return true
end

function main()
    tries = 100000
    success = 0.0
    for i in 1:tries
        if tryit()
            success += 1
        end
    end
    println("Ratio of success = $(success / tries)")
end

main()

我无法用较小的代码示例来重现问题。我在Linux Mint上使用Julia 1.7.2版。

I have the following code that runs in about 8 seconds:

using Random

DEBUG = false
PRISONERS = 100
ATTEMPTS = 50
function tryit()
    a = [1:1:PRISONERS;]
    a = shuffle(a)
    for i in 1:PRISONERS
        if DEBUG
            println("prisoner $i")
        end
        count = 0
        check = i
        while count <= ATTEMPTS
            count += 1
            if a[check] == i
                if DEBUG
                    println("Attempt $count: Checking box $check and found my number")
                end
                break
            else
                if DEBUG
                    println("Attempt $count: Checking box $check and found $(a[check])")    
                end       
                check = a[check]               
            end
        end
           
        if count > ATTEMPTS
            if DEBUG
                println("Prisoner $i failed to find his number in 50 attempts")
            end
            return false
        end
    end
    return true
end

function main()
    tries = 100000
    success = 0.0
    for i in 1:tries
        if tryit()
            success += 1
        end
    end
    println("Ratio of success = $(success / tries)")
end

main()

Moving the global variables inside the function cuts the runtime to a tenth:

using Random

function tryit()
    DEBUG = false
    PRISONERS = 100
    ATTEMPTS = 50
    a = [1:1:PRISONERS;]
    a = shuffle(a)
    for i in 1:PRISONERS
        if DEBUG
            println("prisoner $i")
        end
        count = 0
        check = i
        while count <= ATTEMPTS
            count += 1
            if a[check] == i
                if DEBUG
                    println("Attempt $count: Checking box $check and found my number")
                end
                break
            else
                if DEBUG
                    println("Attempt $count: Checking box $check and found $(a[check])")    
                end       
                check = a[check]               
            end
        end
           
        if count > ATTEMPTS
            if DEBUG
                println("Prisoner $i failed to find his number in 50 attempts")
            end
            return false
        end
    end
    return true
end

function main()
    tries = 100000
    success = 0.0
    for i in 1:tries
        if tryit()
            success += 1
        end
    end
    println("Ratio of success = $(success / tries)")
end

main()

I could not reproduce the problem with a smaller code example. I am using Julia version 1.7.2 on Linux Mint.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你如我软肋 2025-02-20 17:41:54

为什么要全球?如果您担心,因为您想在某些原因下将变量的值保持在函数呼叫时的全局值,则将它们在函数签名中的混音可以解决速度降低问题:

function tryit(PRISONERS = PRISONERS, ATTEMPTS = ATTEMPTS, DEBUG = DEBUG)
   ...

Why globals? If you are concerned because you want to keep the variables' values global at function call for some reason, aliasing them in your function signature can fix the slowdown problem:

function tryit(PRISONERS = PRISONERS, ATTEMPTS = ATTEMPTS, DEBUG = DEBUG)
   ...
天涯离梦残月幽梦 2025-02-20 17:41:54

将全局变量声明为常数解决了问题。

using Random
const DEBUG = false
const PRISONERS = 100
const ATTEMPTS = 50

function tryit()

    a = [1:1:PRISONERS;]
    a = shuffle(a)
    for i in 1:PRISONERS
        if DEBUG
            println("prisoner $i")
        end
        count = 0
        check = i
        while count <= ATTEMPTS
            count += 1
            if a[check] == i
                if DEBUG
                    println("Attempt $count: Checking box $check and found my number")
                end
                break
            else
                if DEBUG
                    println("Attempt $count: Checking box $check and found $(a[check])")    
                end       
                check = a[check]               
            end
        end
           
        if count > ATTEMPTS
            if DEBUG
                println("Prisoner $i failed to find his number in 50 attempts")
            end
            return false
        end
    end
    return true
end

function main()
    tries = 100000
    success = 0.0
    for i in 1:tries
        if tryit()
            success += 1
        end
    end
    println("Ratio of success = $(success / tries)")
end

main()

参见为什么在非相互作用的朱莉娅中,全球变量和局部变量之间存在性能差异程序?用于技术解释。

Declaring the global variables as constants solved the problem.

using Random
const DEBUG = false
const PRISONERS = 100
const ATTEMPTS = 50

function tryit()

    a = [1:1:PRISONERS;]
    a = shuffle(a)
    for i in 1:PRISONERS
        if DEBUG
            println("prisoner $i")
        end
        count = 0
        check = i
        while count <= ATTEMPTS
            count += 1
            if a[check] == i
                if DEBUG
                    println("Attempt $count: Checking box $check and found my number")
                end
                break
            else
                if DEBUG
                    println("Attempt $count: Checking box $check and found $(a[check])")    
                end       
                check = a[check]               
            end
        end
           
        if count > ATTEMPTS
            if DEBUG
                println("Prisoner $i failed to find his number in 50 attempts")
            end
            return false
        end
    end
    return true
end

function main()
    tries = 100000
    success = 0.0
    for i in 1:tries
        if tryit()
            success += 1
        end
    end
    println("Ratio of success = $(success / tries)")
end

main()

See Why is there a performance difference between global and local variables in non-interactive Julia programs? for technical explanations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文