2015-11-06 11 views
6

パラメトリック型の内部コンストラクタの型アノテーションについて少し混乱します。パラメトリック型の内部コンストラクタ

JITの推論効率とランタイム効率の点で、次の4つのアプローチに違いはありますか?

immutable MyType{T} 
    x::T 
    MyType{T}(x::T) = new{T}(x + x) 
end 

immutable MyType{T} 
    x::T 
    MyType(x::T) = new{T}(x + x) 
end 

immutable MyType{T} 
    x::T 
    MyType(x::T) = new(x + x) 
end 

immutable MyType{T} 
    x::T 
    MyType{T}(x::T) = new(x + x) 
end 

これらx = MyType{Int}(1)

答えて

2

のためのすべての作業はパラメトリックタイプの内部コンストラクタを定義する「カノニカル」方法である:

immutable MyType{T<:"specific abstract type"} 
    x::T 
    MyType(x) = new(x + x) 
end 

代わりに任意受け入れることができる一般的な機能MyType(x)を宣言値、ジュリアは自動的に多くの具体的なMyType(x::T)を定義しました。T<:"specific abstract type"です。最後の2つの例はこれと同じです。

私たちが知っているように、newの機能は新しいオブジェクトを作成することです。この関数を呼び出す前に既に制約を適用しているため、パラメトリックにする必要はありません。

がここ
immutable MyType{T<:"specific abstract type"} 
    x::T 
end 

、ジュリアはもう一つん:

MyType{T<:"specific abstract type"}(x::T) = MyType{T}(x)

julia> methods(MyType) 
3-element Array{Any,1}: 
call{T<:Integer}(::Type{MyType{T<:Integer}}, x::T<:Integer) at none:2 
call{T}(::Type{T}, arg) at essentials.jl:56       
call{T}(::Type{T}, args...) at essentials.jl:57 

しかし:外側のコンストラクタを定義

FYI、デフォルトコンストラクタは、上記のものとは異なります。

julia> immutable MyType{T<:Integer} 
      x::T 
      MyType(x) = new(x) 
     end 

julia> methods(MyType) 
2-element Array{Any,1}: 
call{T}(::Type{T}, arg) at essentials.jl:56  
call{T}(::Type{T}, args...) at essentials.jl:57 

これは、カスタムの内部コンストラクタが必要な場合は、その外部コンストラクタを手動で定義する必要がある可能性があることを意味します。

1

Iは、上記の4つの手法用いMyType宣言:次に

immutable MyType1{T} 
    x::T 
    MyType1{T}(x::T) = new{T}(x + x) 
end 
immutable MyType2{T} 
    x::T 
    MyType2(x::T) = new{T}(x + x) 
end 
immutable MyType3{T} 
    x::T 
    MyType3{T}(x::T) = new(x + x) 
end 
immutable MyType4{T} 
    x::T 
    MyType4(x::T) = new(x + x) 
end 

がそれらLLVMバイトコード印刷:code_llvm(MyType1{Int},Int)の出力を比較し、それらが正確に同じであるので、私は4つのアプローチの間には差が存在しないと思います。

関連する問題