gpt4 book ai didi

julia - 为什么我们需要 `iteratoreltype()` ?

转载 作者:行者123 更新时间:2023-12-05 07:39:01 26 4
gpt4 key购买 nike

我不确定我是否理解为什么需要 IteratorEltype()。每个可迭代对象都保证生成 Any 类型的对象,因此如果您不知道更好的方法,那么您可以始终默认为该类型。区分“我知道它可以是任何东西”(IteratorEltype == HasEltype && eltype = Any)和“我不知道它是什么,因此它可以是任何东西”( IteratorEltype == EltypeUnknown)?

我能找到的 Base Julia 中唯一使用 EltypeUnknown() 的类型是 Generator,它是 (f(i) for i在 iter) 语法中。我可以想象,如果 eltype(iter) 是非叶类型,很难/不可能找到这样一个生成器的 eltype,但是 not 的优点是什么在这种情况下,只需将 eltype 设置为 Any 吗?当然,如果 eltype(iter) 是叶类型并且 f 是类型稳定的,您不希望它是 Any,但这两种情况在编译时应该是可以区分的。

最佳答案

两者的区别IteratorEltype()选项如下:

  • HasEltype()说迭​​代器的值应该被视为 eltype() 类型的对象, 即使eltype()比迭代器中实际遇到的类型更通用。

  • EltypeUnknown()询问类似 collect() 的功能找出适用于所有元素的最具体的类型。


示例:

julia> abstract type Wrapper end
Base.length(w::Wrapper) = length(w.data)
Base.iterate(w::Wrapper, s...) = iterate(w.data, s...)

struct EltypeWrapper{T,D} <: Wrapper
data::D
end
EltypeWrapper{T}(data) where T = EltypeWrapper{T,typeof(data)}(data)
Base.eltype(::Type{<:EltypeWrapper{T}}) where T = T

struct EltypeUnknownWrapper{D} <: Wrapper
data::D
end
Base.IteratorEltype(::Type{<:EltypeUnknownWrapper}) = Base.EltypeUnknown()

julia> collect(EltypeWrapper{Any}(Any[1,2.0]))
2-element Array{Any,1}:
1
2.0

julia> collect(EltypeUnknownWrapper(Any[1,2.0]))
2-element Array{Real,1}:
1
2.0

请注意,这两个数组具有相同的条目,但第一个数组的类型为 Vector{Any}而第二个具有类型 Vector{Real} .


看起来HasEltype()应该更有效率,因为它允许在 collect() 等函数中预分配输出.然而,Julia 非常擅长推断迭代器 eltype,并且 EltypeUnknown()可以和 HasEltype() 一样快(或者出于某些奇怪的原因甚至更快) :

julia> using BenchmarkTools

abstract type AbstractIterable end
struct TypedIterable <: AbstractIterable; end
struct UntypedIterable <: AbstractIterable; end

Base.length(::AbstractIterable) = 100000

Base.eltype(::Type{TypedIterable}) = Int
Base.IteratorEltype(::Type{UntypedIterable}) = Base.EltypeUnknown()

function Base.iterate(f::AbstractIterable,i = 1)
i > length(f) && return nothing
return i, i+1
end

@btime collect(UntypedIterable())
@btime collect(TypedIterable())
;
43.033 μs (2 allocations: 781.33 KiB)
56.772 μs (2 allocations: 781.33 KiB)

IteratorEltype()因此不一定会影响使用迭代器的性能,但它可能会严重影响调用堆栈中更上层的性能。如果对叶类型进行操作,几乎所有代码都会快一个数量级,因此可以更快地放入 EltypeUnknown()。作为 IteratorEltype()并希望 eltype()归结为具体类型而不是设置 IteratorEltype() = HasEltype()然后设置 eltype()到一些抽象类型。

关于julia - 为什么我们需要 `iteratoreltype()` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47439004/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com