该代码实现了一个Pollard rho()函数的示例,用于查找正整数n的因子。我已经检查了Julia" Primes"中的一些代码。为了加速pollard_rho()函数而快速运行的包,一切都无济于事。代码应该在大约100毫秒到30秒(Erlang,Haskell,Mercury,SWI Prolog)中执行n = 1524157897241274137,但在JuliaBox,IJulia和Julia REPL上需要大约3到4分钟。我该如何快速完成这项工作?
pollard_rho(1524157897241274137)= 1234567891
__precompile__()
module Pollard
export pollard_rho
function pollard_rho{T<:Integer}(n::T)
f(x::T, r::T, n) = rem(((x ^ T(2)) + r), n)
r::T = 7; x::T = 2; y::T = 11; y1::T = 11; z::T = 1
while z == 1
x = f(x, r, n)
y1 = f(y, r, n)
y = f(y1, r, n)
z = gcd(n, abs(x - y))
end
z >= n ? "error" : z
end
end # module
答案 0 :(得分:12)
这里的类型不稳定存在很多问题。
不要返回字符串"error"
或结果;而是明确地调用error()
。
正如克里斯提到的那样,x
和r
应注释为T
类型,否则它们将不稳定。
溢出似乎也存在潜在问题。解决方案是在截断回T
类型之前扩大平方步骤。
function pollard_rho{T<:Integer}(n::T)
f(x::T, r::T, n) = rem(Base.widemul(x, x) + r, n) % T
r::T = 7; x::T = 2; y::T = 11; y1::T = 11; z::T = 1
while z == 1
x = f(x, r, n)
y1 = f(y, r, n)
y = f(y1, r, n)
z = gcd(n, abs(x - y))
end
z >= n ? error() : z
end
进行这些更改后,该功能将以您预期的速度运行。
julia> @btime pollard_rho(1524157897241274137)
4.128 ms (0 allocations: 0 bytes)
1234567891
要查找类型不稳定的这些问题,请使用@code_warntype
宏。