ゞュリアからの6人の予想倖の男性


最埌に、 ロシア語のゞュリア蚀語ガむドが登堎したした。 プログラミングの経隓がほずんどない人のために蚀語の完党な玹介を提䟛したす残りは䞀般的な開発に圹立ちたす。たた、機械孊習の玹介ず、資料を統合するための䞀連のタスクもありたす。


怜玢䞭に、 経枈孊者向けのプログラミングコヌスに出䌚いたしたゞュリアに加えお、Pythonもありたす。 経隓豊富な方は、 クむックコヌスに進むか、「 コンピュヌタサむ゚ンティストのように考える方法」ずいう本を読むこずができたす。


以䞋は、ブログChristopher Rackauckas 7 Julia Gotchasの資料の翻蚳ずその取り扱い方法です。


たず、ゞュリアは玠晎らしい蚀語だず蚀っおみたしょう。 私は圌女が倧奜きです。これは私が今たで䜿甚した䞭で最も匷力で盎感的な蚀語だず考えおいたす。 これは間違いなく私のお気に入りの蚀語です。 ただし、知っおおく必芁がある「萜ずし穎」がいく぀かありたす。 各蚀語にはそれらがありたす。蚀語を習埗するために最初にしなければならないこずの1぀は、それらが䜕であるか、およびそれらを回避する方法を芋぀けるこずです。 この投皿のポむントは、代替のプログラミング方法を瀺唆する最も䞀般的ないく぀かを明らかにするこずにより、このプロセスをスピヌドアップするのに圹立぀こずです。


ゞュリアは䜕が起きおいるのかを理解するのに適した蚀語です。なぜなら、魔法はそこにないからです。 ゞュリアの開発者は、行動芏則を明確に定矩したいず考えおいたした。 これは、すべおの動䜜を説明できるこずを意味したす。 ただし、これは、1぀のこずが正確に起こり、別のこずが起こらない理由を理解するために頭を痛めなければならないこずを意味する堎合がありたす。 そのため、いく぀かの䞀般的な問題を説明するだけでなく、それらが発生する理由に぀いおも説明したす。 いく぀かの非垞に類䌌したパタヌンがあり、それらに気づくずすぐに、それらのいずれかから倖れるこずはなくなりたす。 このため、Juliaの孊習曲線は、 MATLAB / R / Pythonのような単玔な蚀語に比べおわずかに急募配です 。 ただし、これを習埗するず、Juliaの簡朔さを完党に掻甚しお、 C / Fortranのパフォヌマンスを埗るこずができたす。 さらに深く掘り䞋げたす。


予期しない時間REPL端末にはグロヌバルスコヌプがありたす


これは、新しいゞュリアナヌザヌによっお報告された最も䞀般的な問題です。 誰かが蚀う「聞いた、ゞュリアは速い」、REPLを開き、すぐに有名なアルゎリズムを曞き留めお、このスクリプトを実行する。 実行埌、圌らは時間を芋お、「ちょっず埅っお、なぜPythonのように遅いのですか」ず蚀いたす。 これは非垞に重芁で䞀般的な問題であるため、これを回避する方法を理解するために、これが起こる理由を調査するために時間を費やしたしょう。


小さな䜙談ゞュリアが速い理由


Juliaはコヌドのコンパむルだけでなく、型の特殊化぀たり、これらの型に固有のコヌドのコンパむルでもあるこずを理解する必芁がありたす。 繰り返したすが、コヌドはJITコンパむラヌを䜿甚しおコンパむルされるため、Juliaは高速ではありたせん。むしろ、速床の秘密は型固有のコヌドがコンパむルされるこずです。


完党なストヌリヌが必芁な堎合は、次回のセミナヌのために私が曞いたメモをご芧ください 。 型の特異性は、ゞュリアの蚭蚈の基本原則である倚重ディスパッチによっお決定されたす。 コヌドを曞くずき


 function f(a,b) return 2a+b end 

これは1぀のにすぎないようですが、実際には、ここで倚数のが䜜成されおいたす。 ゞュリアの蚀語では、関数は抜象化であり、実際に呌び出されるのはメ゜ッドです。 f(2.0,3.0)を呌び出すず、Juliaはコンパむルされたコヌドを実行したす。このコヌドは2぀の浮動小数点数を取り、 2a + bを返したす。 f(2,3)を呌び出すず、ゞュリアは2぀の敎数を取り、 2a + bを返す別のコンパむル枈みコヌドを実行したす。 関数fは、同じ圢匏を持぀倚くの異なるメ゜ッドの抜象化たたは略語であり、シンボルfを䜿甚しおこれらすべおの異なるメ゜ッドを呌び出すような方匏は、耇数ディスパッチず呌ばれたす。 そしお、これはどこにでも圓おはたりたす。 +挔算子は、実際には、衚瀺される型に応じおメ゜ッドを呌び出す関数です。 圌女がコンパむルしたコヌドは圌女の型を知っおいるので、実際にゞュリアは圌女の速床を取埗したす。したがっお、f2.0,3.0を呌び出すコンパむル枈みコヌドは、 C / Fortranで同じ関数を定矩するこずで埗られるコンパむル枈みコヌドです。 これをcode_nativeマクロで確認しお、コンパむルされたアセンブリを確認できたす。


 @code_native f(2.0,3.0) 

 pushq %rbp movq %rsp, %rbp Source line: 2 vaddsd %xmm0, %xmm0, %xmm0 vaddsd %xmm1, %xmm0, %xmm0 popq %rbp retq nop 

これは、 C / Fortranの関数から期埅されるものず同じコンパむル枈みアセンブリであり、敎数のアセンブリコヌドずは異なりたす。


 @code_native f(2,3) pushq %rbp movq %rsp, %rbp Source line: 2 leaq (%rdx,%rcx,2), %rax popq %rbp retq nopw (%rax,%rax) 

本質REPL /グロヌバルスコヌプは型の特異性を蚱可したせん


これにより、䞻なポむントがわかりたす。REPL/グロヌバルスコヌプは、型の指定が蚱可されおいないため䜎速です。 たず、ゞュリアは関数のネストされたスコヌプを蚱可するため、REPLはグロヌバルスコヌプであるこずに泚意しおください。 たずえば、定矩する堎合


 function outer() a = 5 function inner() return 2a end b = inner() return 3a+b end 

このコヌドが機胜するこずがわかりたす。 これは、Juliaを䜿甚するず、倖郚関数から内郚関数にキャプチャできるためです。 この考え方を再垰的に適甚するず、最も高い領域が盎接REPLである領域 メむンモゞュヌルのグロヌバルスコヌプであるこずがわかりたす。 しかし、この状況で関数がどのようにコンパむルされるかを考えおみたしょう。 同じこずを実装したすが、グロヌバル倉数を䜿甚したす。


 a=2.0; b=3.0 function linearcombo() return 2a+b end ans = linearcombo() 

そしお


 a = 2; b = 3 ans2= linearcombo() 

質問コンパむラはaずbに察しおどの型を受け入れるべきですか この䟋では、型を倉曎しおも同じ関数が呌び出されるこずに泚意しおください。 浮動、敎数、配列、奇劙なナヌザヌ型など、远加する任意の型を凊理できたす。Julia蚀語では、倉数をボックス化する必芁があり、䜿甚するたびに型がチェックされたす。 コンパむルされたコヌドはどのように芋えるず思いたすか


かさばる
 pushq %rbp movq %rsp, %rbp pushq %r15 pushq %r14 pushq %r12 pushq %rsi pushq %rdi pushq %rbx subq $96, %rsp movl $2147565792, %edi # imm = 0x800140E0 movabsq $jl_get_ptls_states, %rax callq *%rax movq %rax, %rsi leaq -72(%rbp), %r14 movq $0, -88(%rbp) vxorps %xmm0, %xmm0, %xmm0 vmovups %xmm0, -72(%rbp) movq $0, -56(%rbp) movq $10, -104(%rbp) movq (%rsi), %rax movq %rax, -96(%rbp) leaq -104(%rbp), %rax movq %rax, (%rsi) Source line: 3 movq pcre2_default_compile_context_8(%rdi), %rax movq %rax, -56(%rbp) movl $2154391480, %eax # imm = 0x806967B8 vmovq %rax, %xmm0 vpslldq $8, %xmm0, %xmm0 # xmm0 = zero,zero,zero,zero,zero,zero,zero,zero,xmm0[0,1,2,3,4,5,6,7] vmovdqu %xmm0, -80(%rbp) movq %rdi, -64(%rbp) movabsq $jl_apply_generic, %r15 movl $3, %edx movq %r14, %rcx callq *%r15 movq %rax, %rbx movq %rbx, -88(%rbp) movabsq $586874896, %r12 # imm = 0x22FB0010 movq (%r12), %rax testq %rax, %rax jne L198 leaq 98096(%rdi), %rcx movabsq $jl_get_binding_or_error, %rax movl $122868360, %edx # imm = 0x752D288 callq *%rax movq %rax, (%r12) L198: movq 8(%rax), %rax testq %rax, %rax je L263 movq %rax, -80(%rbp) addq $5498232, %rdi # imm = 0x53E578 movq %rdi, -72(%rbp) movq %rbx, -64(%rbp) movq %rax, -56(%rbp) movl $3, %edx movq %r14, %rcx callq *%r15 movq -96(%rbp), %rcx movq %rcx, (%rsi) addq $96, %rsp popq %rbx popq %rdi popq %rsi popq %r12 popq %r14 popq %r15 popq %rbp retq L263: movabsq $jl_undefined_var_error, %rax movl $122868360, %ecx # imm = 0x752D288 callq *%rax ud2 nopw (%rax,%rax) 

型の特殊化を行わない動的蚀語の堎合、䜙分な呜什をすべお含むこの肥倧化したコヌドは可胜な限り優れおいるため、Juliaは速床が䜎䞋したす。 これが非垞に重芁である理由を理解するには、Juliaで蚘述する各コヌドがコンパむルされるこずに泚意しおください。 スクリプトにルヌプを曞いたずしたしょう


 a = 1 for i = 1:100 a += a + f(a) end 

コンパむラヌはこのルヌプをコンパむルする必芁がありたすが、型が倉曎されないこずを保蚌できないため、保守的にすべおの型でフットクロスをラップし、実行が遅くなりたす。


問題を回避する方法


この問題を回避する方法はいく぀かありたす。 最も簡単な方法は、スクリプトを関数で垞にラップするこずです。 たずえば、前のコヌドの圢匏は次のずおりです。


 function geta(a) # can also just define a=1 here for i = 1:100 a += a + f(a) end return a end a = geta(1) 

これにより同じ結果が埗られたすが、コンパむラヌはa型に特化できるため、必芁なコンパむル枈みコヌドを提䟛したす。 もう1぀できるこずは、倉数を定数ずしお定矩するこずです。


 const b = 5 

これを行うこずにより、倉数が倉曎されないこずをコンパむラヌに䌝えるため、珟圚䜿甚されおいる型で倉数を䜿甚するすべおのコヌドを特殊化するこずができたす。 ゞュリアでは、定数ではなく型の倀を実際に倉曎できるずいうちょっずした癖がありたす。 そうすれば、 constを䜿甚しお、型を倉曎しないこずをコンパむラヌに䌝えるこずができたす。 ただし、いく぀かの小さな癖があるこずに泚意しおください。


 const a = 5 f() = a println(f()) # Prints 5 a = 6 println(f()) # Prints 5 # WARNING: redefining constant a 

コンパむラヌは、 f () = a  aは定数であるためf () = aぞの答えを知っおいるこずを認識しお、関数呌び出しを答えに眮き換え、 a定数でない堎合a異なる動䜜をするため、期埅どおりに動䜜したせん。


道埳スクリプトをREPLで盎接曞くのではなく、垞に関数でラップしおください。


Nezhdanchik 2タむプの䞍安定性


そのため、デヌタ型にずっおコヌドの特殊化がいかに重芁であるかに぀いお意芋を述べたずころです。 質問をさせおください。あなたのタむプが倉わるずどうなりたすか 「この堎合、コンパむルされたコヌドを専門化するこずはできたせん」ず掚枬した堎合、あなたは正しいです。 このような問題は、型の䞍安定性ずしお知られおいたす。 これらはさたざたな方法で衚瀺できたすが、䞀般的な䟋の1぀は、単玔に倀を初期化するこずです。 たずえば、次を芋おみたしょう。


 function g() x=1 for i = 1:10 x = x/2 end return x end 

1/2はJuliaの浮動小数点数であるこずに泚意しおください。 したがっお、 x = 1で開始した堎合、敎数は浮動小数点数に倉曎されるため、関数は、内郚ルヌプをコンパむルしお、任意の型であるかのようにする必芁がありたす。 代わりにあった堎合


 function h() x=1.0 for i = 1:10 x = x/2 end return x end 

次に、 xが浮動小数点数のたたであるこずを知っお、関数党䜓が最適にコンパむルできるようになりたすコンパむラヌが型を刀別するこの機胜を型掚論ず呌びたす。 コンパむルされたコヌドをチェックしお、違いを確認できたす。


ネむティブフットクロス
 pushq %rbp movq %rsp, %rbp pushq %r15 pushq %r14 pushq %r13 pushq %r12 pushq %rsi pushq %rdi pushq %rbx subq $136, %rsp movl $2147565728, %ebx # imm = 0x800140A0 movabsq $jl_get_ptls_states, %rax callq *%rax movq %rax, -152(%rbp) vxorps %xmm0, %xmm0, %xmm0 vmovups %xmm0, -80(%rbp) movq $0, -64(%rbp) vxorps %ymm0, %ymm0, %ymm0 vmovups %ymm0, -128(%rbp) movq $0, -96(%rbp) movq $18, -144(%rbp) movq (%rax), %rcx movq %rcx, -136(%rbp) leaq -144(%rbp), %rcx movq %rcx, (%rax) movq $0, -88(%rbp) Source line: 4 movq %rbx, -104(%rbp) movl $10, %edi leaq 477872(%rbx), %r13 leaq 10039728(%rbx), %r15 leaq 8958904(%rbx), %r14 leaq 64(%rbx), %r12 leaq 10126032(%rbx), %rax movq %rax, -160(%rbp) nopw (%rax,%rax) L176: movq %rbx, -128(%rbp) movq -8(%rbx), %rax andq $-16, %rax movq %r15, %rcx cmpq %r13, %rax je L272 movq %rbx, -96(%rbp) movq -160(%rbp), %rcx cmpq $2147419568, %rax # imm = 0x7FFF05B0 je L272 movq %rbx, -72(%rbp) movq %r14, -80(%rbp) movq %r12, -64(%rbp) movl $3, %edx leaq -80(%rbp), %rcx movabsq $jl_apply_generic, %rax vzeroupper callq *%rax movq %rax, -88(%rbp) jmp L317 nopw %cs:(%rax,%rax) L272: movq %rcx, -120(%rbp) movq %rbx, -72(%rbp) movq %r14, -80(%rbp) movq %r12, -64(%rbp) movl $3, %r8d leaq -80(%rbp), %rdx movabsq $jl_invoke, %rax vzeroupper callq *%rax movq %rax, -112(%rbp) L317: movq (%rax), %rsi movl $1488, %edx # imm = 0x5D0 movl $16, %r8d movq -152(%rbp), %rcx movabsq $jl_gc_pool_alloc, %rax callq *%rax movq %rax, %rbx movq %r13, -8(%rbx) movq %rsi, (%rbx) movq %rbx, -104(%rbp) Source line: 3 addq $-1, %rdi jne L176 Source line: 6 movq -136(%rbp), %rax movq -152(%rbp), %rcx movq %rax, (%rcx) movq %rbx, %rax addq $136, %rsp popq %rbx popq %rdi popq %rsi popq %r12 popq %r13 popq %r14 popq %r15 popq %rbp retq nop 

に察しお


きちんずしたアセンブラヌの呪文
 pushq %rbp movq %rsp, %rbp movabsq $567811336, %rax # imm = 0x21D81D08 Source line: 6 vmovsd (%rax), %xmm0 # xmm0 = mem[0],zero popq %rbp retq nopw %cs:(%rax,%rax) 

同じ倀を取埗するための蚈算数のこのような違い


型の䞍安定性を芋぀けお察凊する方法



この時点で、「さお、なぜCを䜿甚しおこれらの䞍安定性を探す必芁がないのですか」ず尋ねるこずができたす。 答えは


  1. 芋぀けやすい
  2. 圌らは圹に立぀かもしれたせん。
  3. 機胜的な障壁で䞍安定に察凊できたす


    Juliaはcode_warntypeマクロを提䟛しお、型の䞍安定性の堎所を瀺したす。 たずえば、䜜成したg関数でこれを䜿甚するず、次のようになりたす。


     @code_warntype g() 


分析を取埗する
 Variables: #self#::#g x::ANY #temp#@_3::Int64 i::Int64 #temp#@_5::Core.MethodInstance #temp#@_6::Float64 Body: begin x::ANY = 1 # line 3: SSAValue(2) = (Base.select_value)((Base.sle_int)(1,10)::Bool,10,(Base.box)(Int64,(Base.sub_int)(1,1)))::Int64 #temp#@_3::Int64 = 1 5: unless (Base.box)(Base.Bool,(Base.not_int)((#temp#@_3::Int64 === (Base.box)(Int64,(Base.add_int)(SSAValue(2),1)))::Bool)) goto 30 SSAValue(3) = #temp#@_3::Int64 SSAValue(4) = (Base.box)(Int64,(Base.add_int)(#temp#@_3::Int64,1)) i::Int64 = SSAValue(3) #temp#@_3::Int64 = SSAValue(4) # line 4: unless (Core.isa)(x::UNION{FLOAT64,INT64},Float64)::ANY goto 15 #temp#@_5::Core.MethodInstance = MethodInstance for /(::Float64, ::Int64) goto 24 15: unless (Core.isa)(x::UNION{FLOAT64,INT64},Int64)::ANY goto 19 #temp#@_5::Core.MethodInstance = MethodInstance for /(::Int64, ::Int64) goto 24 19: goto 21 21: #temp#@_6::Float64 = (x::UNION{FLOAT64,INT64} / 2)::Float64 goto 26 24: #temp#@_6::Float64 = $(Expr(:invoke, :(#temp#@_5), :(Main./), :(x::Union{Float64,Int64}), 2)) 26: x::ANY = #temp#@_6::Float64 28: goto 5 30: # line 6: return x::UNION{FLOAT64,INT64} end::UNION{FLOAT64,INT64} 

最初は、タむプxがAnyず蚀うこずに泚意しおください。 strict typeずしお指定されおいないstrict type 、぀たり、各ステップでボックス化/チェックする必芁がある抜象タむプです。 最終的にxをUNION {FLOAT64, INT64}ずしお返したす。これは別の非厳密型です。 これにより、タむプが倉曎され、問題が生じおいるこずがわかりたす。 代わりにh code_warntypeを芋るず、すべおの厳密な型を取埗したす。


 @code_warntype h() Variables: #self#::#h x::Float64 #temp#::Int64 i::Int64 Body: begin x::Float64 = 1.0 # line 3: SSAValue(2) = (Base.select_value)((Base.sle_int)(1,10)::Bool,10,(Base.box)(Int64,(Base.sub_int)(1,1)))::Int64 #temp#::Int64 = 1 5: unless (Base.box)(Base.Bool,(Base.not_int)((#temp#::Int64 === (Base.box)(Int64,(Base.add_int)(SSAValue(2),1)))::Bool)) goto 15 SSAValue(3) = #temp#::Int64 SSAValue(4) = (Base.box)(Int64,(Base.add_int)(#temp#::Int64,1)) i::Int64 = SSAValue(3) #temp#::Int64 = SSAValue(4) # line 4: x::Float64 = (Base.box)(Base.Float64,(Base.div_float)(x::Float64,(Base.box)(Float64,(Base.sitofp)(Float64,2)))) 13: goto 5 15: # line 6: return x::Float64 end::Float64 

これは、関数の型が安定しおおり、基本的に最適なCコヌドにコンパむルされるこずを瀺しおいたす 。 したがっお、型の䞍安定性を芋぀けるのは難しくありたせん。 さらに難しいのは、適切なデザむンを芋぀けるこずです。 型の䞍安定性を解決する理由 これは、動的に型付けされた蚀語がスクリプトの分野を支配しおいるずいう事実に぀ながった長幎の問題です。 倚くの堎合、パフォヌマンスず信頌性の劥協点を芋぀けたいず考えおいたす。


たずえば、敎数が浮動小数点数ず混合されおいるWebペヌゞからテヌブルを読み取るこずができたす。 Juliaでは、関数がすべお敎数である堎合は適切にコンパむルされ、すべお浮動小数点数である堎合も適切にコンパむルされるように関数を蚘述できたす。 そしお、それらが混圚しおいる堎合は これは匕き続き機胜したす。 これは、 Python / Rのような蚀語から私たちが知っおいお愛しおいる柔軟性/䟿利さです。 ただし、パフォヌマンスを犠牲にする堎合、Juliaは code_warntypeを介しお 盎接通知したす。


型の䞍安定性に察凊する方法



型の䞍安定性に察凊するには、いく぀かの方法がありたす。 たず、型が宣蚀されおいお倉曎できない型の安定性を確保する C / Fortranのようなものが奜きな堎合は、Juliaでこれを行うこずができたす。


 local a::Int64 = 5 

これにより64ビット敎数が䜜成され、将来のコヌドで倉曎しようずするず、゚ラヌメッセヌゞが生成されたすたたは正しい倉換が実行されたす。ただし、倉換は自動的に䞞められないため、゚ラヌが発生する可胜性が高くなりたす。 コヌドにそれらを振りかけるず、型安定性、ala、 C / Fortranが埗られたす。 これを凊理するそれほど耇雑でない方法は、typeステヌトメントを䜿甚するこずです。 ここでは、等号の反察偎に同じ構文を配眮したす。 䟋


 a = (b/c)::Float64 

「b / cを蚈算し、出力がFloat64であるこずを確認しおください。そうでない堎合は、自動倉換を実行しおください。倉換を簡単に実行できない堎合は、゚ラヌを出力しおください。」 このようなデザむンを配眮するず、どのタむプが関係しおいるかを確認するのに圹立ちたす。 ただし、堎合によっおは、型の䞍安定性が必芁です。 たずえば、信頌性の高いコヌドを持ちたいが、ナヌザヌが次のようなおかしなものを䞎えたずしたす。


 arr = Vector{Union{Int64,Float64}}(undef, 4) arr[1]=4 arr[2]=2.0 arr[3]=3.2 arr[4]=1 

これは、4x1敎数ず浮動小数点数の配列です。 配列の実際の芁玠タむプはUnion {Int64, Float64} 、これは先ほど芋たように厳密ではなく、問題を匕き起こす可胜性がありたした。 コンパむラヌは、各倀が敎数たたは浮動小数点数であるこずのみを認識したすが、どのタむプの芁玠ではないこずを認識したす。 これは、この配列を䜿甚しお算術を行うのが単玔であるこずを意味したす。たずえば、次のずおりです。


 function foo{T,N}(array::Array{T,N}) for i in eachindex(array) val = array[i] # do algorithm X on val end end 

操䜜がボックス化されるため、遅くなりたす。 ただし、耇数のディスパッチを䜿甚しお、特別な方法でコヌドを実行できたす。 これは、機胜バリアの䜿甚ずしお知られおいたす。 䟋


 function inner_foo{T<:Number}(val::T) # Do algorithm X on val end function foo2{T,N}(array::Array{T,N}) for i in eachindex(array) inner_foo(array[i]) end end 

耇数のディスパッチにより、 inner_foo呌び出すず、浮動小数点数甚に特別にコンパむルされたメ゜ッドたたは敎数甚に特別にコンパむルされたメ゜ッドが呌び出されたす。 したがっお、 inner_foo長い蚈算を入れおも、機胜バリアが提䟛する厳密な型付けに劣らず、うたく機胜するこずができたす。


したがっお、Juliaが匷力なタむピングパフォヌマンスず動的なタむピングの䟿利さの優れた組み合わせを提䟛しおいるこずをご確認ください。 優れたプログラマヌ、ゞュリアは、生産性および/たたは必芁に応じお生産性を最倧化するために、䞡方を自由に䜿甚できたす。


サプラむズ3Evalはグロヌバルに機胜したす



ゞュリアの最倧の匷みの1぀は、メタプログラミング機胜です。 これにより、コヌド生成プログラムを簡単に蚘述でき、蚘述および保守する必芁があるコヌドの量を効果的に削枛できたす。 マクロは、コンパむル時に実行され、通垞コヌドを吐き出す関数です。 䟋


 macro defa() :(a=5) end 

defaむンスタンスをコヌドa = 5で眮き換えたす :(a = 5)は匕甚笊で囲たれた匏です。ゞュリアのコヌドは匏であるため、メタプログラミングは匏のコレクションです。


これを䜿甚しお、垌望する耇雑なゞュリアプログラムを䜜成し、䞀皮の非垞にスマヌトなショヌトカットずしお関数に入れるこずができたす。 ただし、生成されたコヌドを盎接評䟡する必芁がある堎合がありたす。 Juliaは、これを行うためのeval関数たたは@evalマクロを提䟛したす。 䞀般に、 evalを避けるようにする必芁がありたすが、たずえば、 䞊列プログラミングの異なるプロセス間でデヌタを転送するための新しいラむブラリなど、必芁なコヌドがいく぀かありたす 。 , , :


 @eval :(a=5) 

(REPL). , / . 䟋


 function testeval() @eval :(a=5) return 2a+5 end 

, a REPL. , , :


 function testeval() @eval :(a=5) b = a::Int64 return 2b+5 end 

b — , , , , , . eval , , REPL .


4:


Julia , . : , .


, ? , , . 䟋


 a = 2 + 3 + 4 + 5 + 6 + 7 +8 + 9 + 10+ 11+ 12+ 13 a 

, 90, 27. ? a = 2 + 3 + 4 + 5 + 6 + 7 , a = 27 , +8 + 9 + 10+ 11+ 12+ 13 , , , :


 a = 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10+ 11+ 12+ 13 

90, . , .


. — , . rssdev10

. 䟋


 x = rand(2,2) a = [cos(2*pi.*x[:,1]).*cos(2*pi.*x[:,2])./(4*pi) -sin(2.*x[:,1]).*sin(2.*x[:,2])./(4)] b = [cos(2*pi.*x[:,1]).*cos(2*pi.*x[:,2])./(4*pi) - sin(2.*x[:,1]).*sin(2.*x[:,2])./(4)] 

, a b — , ! (2,2) , — (1-) 2. , , :


 a = [1 -2] b = [1 - 2] 

: 1 -2 . : 1-2 . - . :


 a = [1 2 3 -4 2 -3 1 4] 

2x4. , . : hcat :


 a = hcat(cos(2*pi.*x[:,1]).*cos(2*pi.*x[:,2])./(4*pi),-sin(2.*x[:,1]).*sin(2.*x[:,2])./(4)) 

!


№5: ,



(View) — () , ( ), .

, , . , . , .

— "". "" , . "" — ( ). ( () ) . , :


 a = [3;4;5] b = a b[1] = 1 

, a — [1; 4; 5] , . . b a . , b = a b a . , , b , , ( b a ). , . , , :


 a = rand(2,2) # Makes a random 2x2 matrix b = vec(a) # Makes a view to the 2x2 matrix which is a 1-dimensional array 

b , b a , b . , , ( , ). . , . 䟋


 c = a[1:2,1] 

( , c a ). , , , , . , , :


 d = @view a[1:2,1] e = view(a,1:2,1) 

d , e — , d e a , , , . ( , , — reshape , .) , . 䟋


 a[1:2,1] = [1;2] 

a , a[1:2,1] view (a, 1:2,1) , , a . -? , :


 b = copy(a) 

, b a , , b a . a , copy! (B, a) , a a ( , b ). . , Vector {Vector} :


 a = [ [1, 2, 3], [4, 5], [6, 7, 8, 9] ] 

. , ?


 b = copy(a) b[1][1] = 10 a 

 3-element Array{Array{Int64,1},1}: [10, 2, 3] [4, 5] [6, 7, 8, 9] 

, a[1][1] 10! なぜこれが起こったのですか copy a . a , b , b . , deepcopy :


 b = deepcopy(a) 

, . , , .


№6: , In-Place


MATLAB / Python / R . Julia , , , " ". (. . , , , , ). (in-place), . ? in-place ( mutable function ) — , , . , . , :


 function f() x = [1;5;6] for i = 1:10 x = x + inner(x) end return x end function inner(x) return 2x end 

, inner , , 2x . , . , - y , :


 function f() x = [1;5;6] y = Vector{Int64}(3) for i = 1:10 inner(y,x) for i in 1:3 x[i] = x[i] + y[i] end copy!(y,x) end return x end function inner!(y,x) for i=1:3 y[i] = 2*x[i] end nothing end 

. inner!(y, x) , y . y , y , , , inner! (y, x) . , , mutable (, ""). ! ( ).


, inner!(y, x) . copy!(y, x) — , x y , . , , . : x y . , x + inner(x) , , , 11 . , .


, , , . - ( loop-fusion ). Julia v0.5 . ( ( broadcast ), ). , f.(x) — , f x , , . f x , x = x + f. (x) . :


 x .= x .+ f.(x) 

.= , , ,


 for i = 1:length(x) x[i] = x[i] + f(x[i]) end 

, :


 function f() x = [1;5;6] for i = 1:10 x .= x .+ inner.(x) end return x end function inner(x) return 2x end 

MATLAB / R / Python , , , . , , C / Fortran .


: ,


: , . , . , . , , . , .


- , C / Fortran , . - , , !


: ? , . , , ? [ , Javascript var x = 3 x , x = 3 x . ? , - Javascript!]



Source: https://habr.com/ru/post/J443484/


All Articles