gpt4 book ai didi

julia - 如何制作更强大的类型压缩/解压缩?

转载 作者:行者123 更新时间:2023-12-01 05:00:35 27 4
gpt4 key购买 nike

我有一个 Array{Tuple{A, B}} , 我想解压/转置成 Tuple{Array{A}, Array{B}} .

typealias MyIndexType Tuple{Bool, Int}

function test(x::MyIndexType)
# prepare for test data set.
myArray = Array{Tuple{MyIndexType, Float64}}(0)
push!(myArray, (x,1))
push!(myArray, (x,1))
push!(myArray, (x,1))

# transform
a, b = (zip(myArray...)...)
[a...]
end

test((true, 1))

>>>
3-element Array{Tuple{Bool,Int64},1}:
(true,1)
(true,1)
(true,1)

但是,使用 @code_warntype , JIT 无法推断 a 的类型, b提前时间。
Variables:
x::Tuple{Bool,Int64}
myArray::Array{Tuple{Tuple{Bool,Int64},Float64},1}
a::ANY
b::ANY
#s41::Int64

Body:
begin # In[47], line 6:
myArray = (top(ccall))(:jl_alloc_array_1d,(top(apply_type))(Base.Array,Tuple{Tuple{Bool,Int64},Float64},1)::Type{Array{Tuple{Tuple{Bool,Int64},Float64},1}},(top(svec))(Base.Any,Base.Int)::SimpleVector,Array{Tuple{Tuple{Bool,Int64},Float64},1},0,0,0)::Array{Tuple{Tuple{Bool,Int64},Float64},1} # In[47], line 7:
(Main.push!)(myArray::Array{Tuple{Tuple{Bool,Int64},Float64},1},(top(tuple))(x::Tuple{Bool,Int64},1)::Tuple{Tuple{Bool,Int64},Int64})::Array{Tuple{Tuple{Bool,Int64},Float64},1} # In[47], line 8:
(Main.push!)(myArray::Array{Tuple{Tuple{Bool,Int64},Float64},1},(top(tuple))(x::Tuple{Bool,Int64},1)::Tuple{Tuple{Bool,Int64},Int64})::Array{Tuple{Tuple{Bool,Int64},Float64},1} # In[47], line 9:
(Main.push!)(myArray::Array{Tuple{Tuple{Bool,Int64},Float64},1},(top(tuple))(x::Tuple{Bool,Int64},1)::Tuple{Tuple{Bool,Int64},Int64})::Array{Tuple{Tuple{Bool,Int64},Float64},1} # In[47], line 10:
GenSym(0) = (top(_apply))((top(getfield))(Main,:call)::F,top(tuple),(top(_apply))((top(getfield))(Main,:call)::F,Main.zip,myArray::Array{Tuple{Tuple{Bool,Int64},Float64},1})::UNION{BASE.ZIP2{TUPLE{TUPLE{BOOL,INT64},FLOAT64},TUPLE{TUPLE{BOOL,INT64},FLOAT64}},TUPLE{TUPLE{BOOL,INT64},FLOAT64},ZIP{I,Z<:BASE.ABSTRACTZIPITERATOR}})::TUPLE
#s41 = 1
GenSym(4) = (Base.getfield)(GenSym(0),1)::ANY
GenSym(5) = (Base.box)(Base.Int,(Base.add_int)(1,1)::ANY)::Int64
a = GenSym(4)
#s41 = GenSym(5)
GenSym(6) = (Base.getfield)(GenSym(0),2)::ANY
GenSym(7) = (Base.box)(Base.Int,(Base.add_int)(2,1)::ANY)::Int64
b = GenSym(6)
#s41 = GenSym(7) # In[47], line 11:
return (top(_apply))((top(getfield))(Main,:call)::F,top(vect),a)::ANY
end::ANY

有没有办法让 zip 知道结果类型?

更新

其实有2个问题。
  • 它认为a类型为 a::TUPLE{UNION{FLOAT64,INT64},UNION{FLOAT64,INT64}} ,但它实际上是类型 a::TUPLE{FLOAT64,FLOAT64}
    function test{T}(x::T)
    A = Tuple{T, Int}[]

    for i in 1:3
    push!(A, (x, 1))
    end

    d = zip(A[1], A[2])
    a, b = d
    a
    end

    @code_warntype test(3.0)


    Variables:
    x::Float64
    A::Array{Tuple{Float64,Int64},1}
    d::Base.Zip2{Tuple{Float64,Int64},Tuple{Float64,Int64}}
    a::TUPLE{UNION{FLOAT64,INT64},UNION{FLOAT64,INT64}}
    b::TUPLE{UNION{FLOAT64,INT64},UNION{FLOAT64,INT64}}
    #s40::Tuple{Int64,Int64}
    #s41::Int64
    i::Int64
  • 对于 zip采用 2 个以上的参数,注意 d 有一个嵌套的 zip2类型,我觉得这可能会给类型推断带来负担。
    function test{T}(x::T)
    A = Tuple{T, Int}[]

    for i in 1:3
    push!(A, (x, 1))
    end

    d = zip(A[1], A[2], A[3])
    a, b = d
    a
    end

    @code_warntype test(3.0)

    Variables:
    x::Float64
    A::Array{Tuple{Float64,Int64},1}


    d::Zip{Tuple{Float64,Int64},Base.Zip2{Tuple{Float64,Int64},Tuple{Float64,Int64}}}
    a::TUPLE{UNION{FLOAT64,INT64},UNION{FLOAT64,INT64},UNION{FLOAT64,INT64}}
    b::TUPLE{UNION{FLOAT64,INT64},UNION{FLOAT64,INT64},UNION{FLOAT64,INT64}}
    #s40::Tuple{Int64,Tuple{Int64,Int64}}
    #s41::Int64
    i::Int64
    ##c#7879::Tuple{Tuple{Float64,Int64}}

  • 我为什么关心类型?

    编译下面例子的a,b = zip(A...)需要10+秒,速度好像和A的长度有关。(Julia 0.4)
    const A = Tuple{Int, Int}[]

    for i = 1:200
    push!(A, (1, 1))
    end

    a, b = zip(A...)
    a

    我在这里打开了一个错误报告 https://github.com/JuliaLang/julia/issues/13722

    最佳答案

    我相信@code_warntype不是问题报告说,如果它最终正确,则无法推断出正确的类型。

    尽管如此,我还是想知道这是否是由于您的类型的复杂性。但事实并非如此,如下面的代码所示(使用更简单的类型)。

    请注意,您还可以简化您的 zip表达;你可能不需要转换 a到一个数组。

    代码:

    function test{T}(x::T)
    A = Tuple{T, Int}[]

    for i in 1:3
    push!(A, (x, 1))
    end

    a, b = zip(A...)
    a, b
    end

    julia> test(3) # now returns a and b
    ((3,3,3),(2,2,2))

    julia> @code_warntype test(3)
    Variables:
    x::Int64
    A::Array{Tuple{Int64,Int64},1}
    a::ANY
    b::ANY
    #s40::ANY
    #s41::Int64
    i::Int64

    关于julia - 如何制作更强大的类型压缩/解压缩?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33271306/

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