Types 为什么这个简单的索引变量会在Julia中出现?

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

在手动从Project Euler求解时(而不是简单地使用素数
),我在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