Types 为什么这个简单的索引变量会在Julia中出现?
在手动从Project Euler求解时(而不是简单地使用素数Types 为什么这个简单的索引变量会在Julia中出现?,types,julia,type-inference,type-stability,Types,Julia,Type Inference,Type Stability,在手动从Project Euler求解时(而不是简单地使用素数),我在Julia中使用位向量实现了一个简单的Eratosthenes筛选。它产生正确的输出,但是当我使用@code\u warntype检查它的类型稳定性时,我发现I被分配为Core.Box,这会影响psum的类型,反过来又会影响整个函数的类型稳定性。这是使用的代码: function primesum(limit::T = 2_000_000) where T<:Integer #easy way: using Pr
),我在Julia中使用位向量实现了一个简单的Eratosthenes筛选。它产生正确的输出,但是当我使用@code\u warntype
检查它的类型稳定性时,我发现I
被分配为Core.Box
,这会影响psum
的类型,反过来又会影响整个函数的类型稳定性。这是使用的代码:
function primesum(limit::T = 2_000_000) where T<:Integer
#easy way: using Primes; sum(primes(limit))
#hard way:
is_prime_num = BitVector(limit)
is_prime_num .= true
psum = zero(limit)
for i in 2:limit
if is_prime_num[i]
psum += i
multiples_of_i = [k*i for k in 2:(limit÷i)]
is_prime_num[multiples_of_i] .= false
end
end
psum
end
总的来说,代码中的许多类型(包括函数的返回类型)都保留为Any
或where
类型
我能够通过将for
循环行更改为for I::T in 2:limit
,来提高速度(几乎10倍)和内存(~3倍)——然后,I
仍然被设置为核心.Box
,但这会将类型断言
转换为Int64,并且不会将不稳定性传播到psum
和其他人。但是我更感兴趣的是为什么Julia不能推断出I
的类型,而不是加速这个特定的代码。我习惯于键入不稳定性,至少回想起来是有意义的,但这一点似乎很清楚,也很容易推断,所以我想知道这里哪里存在类型歧义 一个临时解决方案是将i
包装在中,让阻塞理解(我也在你的代码中提出了一些小的调整,这些小的调整是次要的清理-我留下了创建multiples\u of_I
,因为这是你问题的核心,但实际上使用这个变量也是低效的-最好在适当的地方使用循环将is_prime_num
vector设置为false
):
希望从长远来看,该问题将得到解决,而这将不再需要。谢谢,很高兴知道它作为一个已知问题被跟踪。在这种情况下,是列表理解在我内部关闭了吗?是否有一些关于理解是如何实现的文档?AFAIK是唯一可以找到理解的地方在julia-syntax.scm文件中,有两个字符。相关代码从该文件的第2327行开始。这是一个很难读懂的代码。这看起来很吸引人。确实需要彻底的阅读和上下文知识,但scm文件的结构和可读性都比我预期的要好得多。谢谢你的回答和指针。
Variables:
#self#::#primesum
limit::Int64
#46::##46#47
i::Core.Box
multiples_of_i::Any
#temp#@_6::Int64
is_prime_num::BitArray{1}
psum::Any
J::Any
#temp#@_10::Any
function primesum(limit::Integer = 2_000_000)
is_prime_num = trues(limit)
psum = zero(limit)
for i in 2:limit
if is_prime_num[i]
psum += i
let i=i
multiples_of_i = [k*i for k in 2:(limit÷i)]
is_prime_num[multiples_of_i] .= false
end
end
end
psum
end