我有两个似乎执行相同操作的代码版本:

sum = 0
for x in 1:100
    sum += x
end
sum = 0
for x in collect(1:100)
    sum += x
end

两种方法之间有实际区别吗?

#1楼 票数:4

UnitRange将使用恒定空间,而Array将与要迭代的元素数量成比例增长。

您可以使用BenchmarkTools包查看差异。

julia> @btime sum(1:1000000)
  0.044 ns (0 allocations: 0 bytes)
500000500000

julia> @btime sum(collect(1:1000000))
  1.123 ms (2 allocations: 7.63 MiB)
500000500000

两种方法在时空性能上都存在显着差异。 当您一次不需要全部内存时, UnitRange避免了分配大量内存的工作。 如果可能,最好使用UnitRange不是Array

#2楼 票数:3 已采纳

在Julia中, 1:100返回一个称为UnitRange的特殊结构,如下所示:

julia> dump(1:100)
UnitRange{Int64}
  start: Int64 1
  stop: Int64 100

这是一个非常紧凑的结构,用于表示具有步骤1和任意(有限)大小的范围。 UnitRange是亚型AbstractRange ,一个类型来表示任意步骤,亚型范围AbstractVector

每当您使用getindex (或语法糖vector[index] )时, UnitRange的实例UnitRange动态计算其元素。 例如,使用@less (1:100)[3]您可以看到此方法:

function getindex(v::UnitRange{T}, i::Integer) where {T<:OverflowSafe}
    @_inline_meta
    val = v.start + (i - 1)
    @boundscheck _in_unit_range(v, val, i) || throw_boundserror(v, i)
    val % T
end

这是通过将i - 1与范围的第一个元素( start )相加来返回向量的第i个元素。 一些函数使用UnitRange或更优化地使用AbstractRange优化了方法。 例如,使用@less sum(1:100)您可以看到以下内容

function sum(r::AbstractRange{<:Real})
    l = length(r)
    # note that a little care is required to avoid overflow in l*(l-1)/2
    return l * first(r) + (iseven(l) ? (step(r) * (l-1)) * (l>>1)
                                     : (step(r) * l) * ((l-1)>>1))
end

此方法将公式用于算术级数的总和 ,这是非常有效的,因为它在与向量大小无关的时间内进行求值。

另一方面, collect(1:100)返回一个带有一百个元素1、2、3,...,100的简单Vector 。与UnitRange (或其他类型的AbstractRange )的主要区别是getindex(vector::Vector, i) (或具有vector::Vector vector[i] )不执行任何计算,而只是访问向量的第i个元素。 VectorUnitRange上的UnitRange是,一般来讲,使用它们时没有有效的方法,因为此容器的元素是完全任意的,而UnitRange表示一组具有特殊属性(排序,恒定步长等)的数字。 ..)。

如果比较UnitRange具有超高效实现的方法的性能,则此类型将UnitRange (请注意,在使用BenchmarkTools宏时,请使用$(...)对变量进行插值):

julia> using BenchmarkTools

julia> @btime sum($(1:1000_000))
  0.012 ns (0 allocations: 0 bytes)
500000500000

julia> @btime sum($(collect(1:1000_000)))
  229.979 μs (0 allocations: 0 bytes)
500000500000

请记住,每次使用getindex访问UnitRange都会带来动态计算元素的成本。 例如考虑以下功能:

function test(vec)
    sum = zero(eltype(vec))
    for idx in eachindex(vec)
        sum += vec[idx]
    end
    return sum
end

让我们用UnitRange和一个普通的Vector基准测试:

julia> @btime test($(1:1000_000))
  812.673 μs (0 allocations: 0 bytes)
500000500000

julia> @btime test($(collect(1:1000_000)))
  522.828 μs (0 allocations: 0 bytes)
500000500000

在这种情况下,调用普通数组的函数比使用UnitRange的函数要快,因为它不必动态计算100万个元素。

当然,在这些玩具示例中,遍历vec所有元素而不是索引要更明智,但是在现实世界中,这种情况可能更明智。 但是,最后一个示例显示UnitRange不一定比普通数组更有效,尤其是在需要动态计算其所有元素的情况下。 当您可以利用可以在恒定时间内执行操作的专用方法(例如sum )时, UnitRange的效率更高。

作为文件说明,请注意,如果您最初有一个UnitRange ,将其转换为纯Vector以获得良好的性能不一定是个好主意,尤其是如果您仅使用一次或很少使用它,则该转换Vector本身涉及范围所有元素的动态计算以及必要内存的分配:

julia> @btime collect($(1:1000_000));
  422.435 μs (2 allocations: 7.63 MiB)

julia> @btime test(collect($(1:1000_000)))
  882.866 μs (2 allocations: 7.63 MiB)
500000500000

  ask by David Varela translate from so

未解决问题?本站智能推荐:

1回复

Julia中的Array {Bool}和BitArray有什么区别?它们有什么关系?

我正在为布尔2d数组编写一个函数: 用它评估和测试它 回报 显然, randbool()生成一个BitArray ,而我假设randbool()会产生一个Array{Bool} 。 Array{Bool}和BitArray相关? 为什么它们都存在? 我可以用
2回复

Julia 和 Julia Pro 有什么区别?

Julia Computing 提供的 Julia 和 Julia Pro 有什么区别? Julia Pro 是否有任何在 Julia 中不可用的企业库?
1回复

Julia中的UnitRange类型是什么意思?

我尝试阅读具有OOP强类型背景的Julia代码 。 我得到了大部分,但是UnitRange{Int}; 它的使用方式对我来说并不清楚:它是一个数组还是一个整数? 任何人都可以在一些强类型语言中UnitRange类型的模拟吗?
1回复

数据类型-data.array和array之间的区别

所以我正在使用指标包和sma函数。 sma函数的设置如下: 它的输入是Array {Float64}。 所以我将数据加载到具有以下类型的df中: 然后,我尝试直接在数据框列上运行sma函数,如下所示: 它报告: 我看到的类型是: DataArray
1回复

尝试在 Julia 中对 Vector 使用 UnitRange 进行索引时出错

我正在尝试将一些 Python 代码翻译成 Julia ..但是在寻找一个示例时遇到了麻烦,我有一个范围,然后我可以将其应用于矩阵或向量以进行索引......这是我的代码 来源: https : //cs231n.github.io/neural-networks-case-study/ Pyt
2回复

朱莉娅:地图和广播有什么区别?

我在 Julia 用户组上找到了一些讨论,但它们对我来说太技术性了。 我想知道在两者之间进行选择的标准是什么。 我正在关注 JuliaBox 教程,但它没有解释太多。 谢谢
1回复

Mapreduce 和 Filter 与 Julia 中的 sum 有什么区别?

朱莉娅版本:1.4.0 我有这两个片段,我认为它们应该是等效的,但是它们产生了非常不同的结果。 我错过了什么? 样本是具有 1000000 个元素的Vector{Float64} 。 此外,它是后验分布的随机抽样。
2回复

METADATA和METADATA.jl:有什么区别?

在阅读了手册之后,我仍然不清楚这两件事。 两者都是目录,尽管.jl使您认为一个文件是Julia源文件,但不是,它是目录。 两者似乎具有相似的内容: 该文档说: 分叉主要的METADATA存储库 要么 从git://github.com/JuliaLang/