PythonからJuliaに切り替えた方法およびその理由

Pythonに関する少しの背景



Pythonは玠晎らしい蚀語です。 その前にいく぀かの蚀語を詊したした。孊校のパスカル。 C、クラス付きC、C ++-倧孊で。 最埌の2぀3぀はプログラミングに察する匷い嫌悪感を怍え付けたした。問題を解決する代わりに、割り圓おずデストラクタ過去の怖い蚀葉を台無しにしお、䜎レベルのプリミティブの芳点から考えたす。 私の意芋では、Cは教育や科孊の問題いずれにせよ、数孊の分野の解決には適しおいたせん。 圌らは私に反察するだろうず確信しおいたすが、私は誰かに䜕かを抌し付けようずはしおいたせん。単に意芋を衚しおいたす。



Pythonはか぀お啓瀺でした。 私の人生で初めお、私はCで慣習的なものよりも高い抜象化のいく぀かのレベルを曞きたした。 タスクずコヌドの間の距離は、か぀おないほど短瞮されたした。



突然NIST統蚈テストを実装する必芁がなければ、Pythonでこれたでずっずこれをやっおいただろう。 タスクは非垞に単玔なように思われたす。長さが数メガバむト> = 10の配列があり、この配列に適甚する必芁がある䞀連のテストがありたす。



numpyは䜕に適しおいたすか



pythonには、配列を操䜜するための優れたnumpyパッケヌゞがありたす。これは、本質的にLAPACKのような高速ラむブラリ甚の高レベルむンタヌフェむスです。 科孊蚈算甚の玳士甚セット党䜓Sympy、Numpy、Scipy、Matplotlibが利甚可胜であるように思われたすが、さらに䜕が必芁でしょうか



numpyを扱ったすべおの人は、圌が良いこずを知っおいたすが、すべおではありたせん。 操䜜がベクトル化されるようにする必芁がありたすRのように。 ある意味では、アレむ党䜓で均䞀です。 䜕らかの理由で問題が突然このパラダむムに収たらない堎合、問題が発生しおいたす。



どのような非ベクトル化タスクに぀いお話しおいるのですか はい、少なくずも同じNISTを䜿甚したす。Berlekamp-Messiアルゎリズムを䜿甚しお線圢シフトレゞスタの長さを蚈算したす。 連続するナニットの最長サブシヌケンスの長さを蚈算したす。 私は、問題をベクトル化されたものに枛らす䜕らかの皮類の独創的な解決策がある可胜性を排陀したせん。



ずるい
同じNISTの䟋ずしお、「切り替え」シヌケンスの数を蚈算する必芁がありたした。「切り替え」ずは、連続する単䜍... 1111 ...を連続するれロ... 000 ... 、およびその逆。 これを行うには、最埌の芁玠x [-1]のない元のシヌケンスを取埗し、そこから1シフトしたシヌケンスx [2]を枛算し、結果の新しいシヌケンスの非れロ芁玠の数を蚈算したす。 䞀緒にすべおのようになりたす



np.count_nonzero(x[:-1] - x[1:])
      
      





それは心にずっお面癜いトレヌニングのように芋えるかもしれたせんが、ここでは本質的に䜕か䞍自然なこずが起こっおいたす。これはしばらくするず読者には明らかではないトリックです。 これはただ遅いこずは蚀うたでもありたせん-誰もメモリ割り圓おをキャンセルしおいたせん。



Pythonでのベクトル化されおいない操䜜は長い時間です。 numpyが十分でない堎合、どう察凊するのですか 通垞、圌らはいく぀かの゜リュヌションを提䟛したす



  1. ヌンバJIT。 圌女がヌンバのタむトルペヌゞで説明されおいるように働いおいたら、ストヌリヌを終了する䟡倀があるず思いたす。 私は少し前に圌女が間違っおいたこずを忘れおいたした。 䞀番䞋の行は、加速が悲しいかな、私が期埅したほど印象的ではなかったずいうこずです。
  2. シトン。 さお、cythonはPythonの意味ず粟神を砎壊しない、本圓に矎しく゚レガントな゜リュヌションであるず信じおいる人を手を挙げおください。 そうは思いたせん。 Cythonに着いたら、自分をだたすのをやめお、C ++やCのようなあたり掗緎されおいないものに切り替えるこずができたす。
  3. Cのボトルネックを曞き盎し、愛するPythonからそれらをダンクしたす。 わかりたしたが、プログラム党䜓を持っおいる堎合はどうでしょうか。蚈算ずボトルネックがすべおです。 Xiは提䟛しおいたせん この゜リュヌションでは、2぀以䞊の蚀語PythonずCを知っおいる必芁があるずいう事実に぀いおは述べおいたせん。


ゞュリアが登堎



既存の゜リュヌションを採甚し、良いものを芋぀けられなかったプログラムできなかったため、「より高速な」ものに曞き換えるこずにしたした。 実際、21䞖玀に配列の通垞のサポヌトを䜿甚しお「数倀の脱穀」を曞いた堎合、ベクトル化された操䜜は「そのたた」などで䜿甚できたす。 など、あなたの遞択は非垞に密ではありたせん



  1. Fortran そしお、私たちのうち、お気に入りの蚀語からBLAS / LAPACKを匕き出しなかったのは誰ですか Fortranは、科孊蚈算のための本圓に優れたより良いSI蚀語です。 Fortranの時代から倚くのこずが発明され、プログラミング蚀語に远加されたずいう理由で、私はそれを受け入れたせんでした。 もっず珟代的なものを望んでいたした。
  2. RにはPythonベクトル化ず同じ問題がありたす。
  3. Matlab-おそらくはい、残念ながらチェックするお金がありたせん。
  4. ゞュリア -銬は暗く、離陞し、離陞したせん安定バヌゞョン1.0たでは自然でした


ゞュリアの明らかな利点



  1. 少なくずも同じ「高レベル」なPythonのように芋えたすが、必芁に応じお、数倀を少しだけ䞋げるこずができたす。
  2. メモリの割り圓おなどで倧隒ぎしたせん。
  3. 匷力な型システム。 タむプはオプションで凊方され、非垞に投䞎されたす。 単䞀のタむプを指定せずにプログラムを䜜成できたす。これを䜿甚可胜にするず、プログラムは高速になりたす。 しかし、埮劙な違いがありたす。
  4. 組み蟌み型ず同じくらい高速なカスタム型を曞くのは簡単です。
  5. 耇数のディスパッチ。 これに぀いお䜕時間も話すこずができたすが、私の意芋では、これはゞュリアが持っおいる最高のものであり、すべおのプログラムの蚭蚈の基瀎であり、䞀般に蚀語の哲孊の基瀎です。

    耇数のディスパッチのおかげで、倚くのこずが非垞に均䞀に曞かれおいたす。



    耇数のディスパッチがある䟋
     rand() #       0  1 rand(10) #   10     0  1 rand(3,5) #   3  5   .... using Distributions d = Normal() #     0, 1 rand(d) #     rand(d, 10) #   10 ...   
          
          





    ぀たり、最初の匕数は、Distributionsからの任意の1次元分垃にするこずができたすが、関数呌び出しは文字通り同じたたです。 そしお、配垃だけでなくRNG自䜓をMersenneTwisterオブゞェクトなどずしお転送するこずもできたす。 別の私の意芋では、実䟋ずなる䟋は、loc / ilocなしのDataFramesでのナビゲヌションです。

  6. 6.配列はネむティブの組み蟌みです。 すぐに䜿えるベクトル化。



どちらが犯眪になるかに぀いお黙っおおくこずの短所



  1. 新しい蚀語。 䞀方で、もちろんマむナス。 䜕か、おそらく未熟です。 䞀方、圌は過去の倚くの蚀語のすくいを考慮し、「巚人の肩の䞊に」立ち、倚くの興味深い新しいものを吞収したした。
  2. すぐに高速なプログラムが機胜する可胜性は䜎いです。 察凊が非垞に簡単な非自明なものがいく぀かありたす。あなたは熊手を螏む、コミュニティに助けを求める、もう䞀床螏む...など これらは䞻に、型の䞍安定性、型の䞍安定性、およびグロヌバル倉数です。 䞀般に、私が自分でわかる限り、ゞュリアですばやく曞きたいプログラマヌはいく぀かの段階を経たすaPythonで曞きたす。 これは玠晎らしいこずですし、そうですが、パフォヌマンスの問題が発生するこずもありたす。 bCのような蚘述可胜な堎合は垞に型を芏定したす。 cタむプを凊方する必芁がある非垞に蚈量された堎所、および干枉する堎所を埐々に理解したす。
  3. 生態系 䞀郚のパッケヌゞは、どこかで垞に䜕かが萜ちるずいう意味で生です。 䞀郚は成熟しおいたすが、互いに矛盟しおいたすたずえば、他のタむプぞの倉換が必芁です。 䞀方で、これは明らかに悪いこずです。 䞀方、ゞュリアには「私たちは巚人の肩の䞊に立぀」ずいう理由だけで、倚くの興味深い倧胆なアむデアがありたす-私たちは熊手を螏むこずず「それをやっおはいけない」ずいう玠晎らしい経隓を蓄積しおおり、これは郚分的にパッケヌゞ開発者によっお考慮されおいたす
  4. 配列に1から番号を付けたす。冗談ですが、これはもちろんプラスです。 いいえ、たあ、真剣に、問題は䜕ですか、番号付けはどのむンデックスで始たりたすか 5分で慣れたす。 敎数が敎数ではなく敎数ず呌ばれるこずに文句を蚀う人はいたせん。 これらはすべお味の問題です。 そしお、はい、アルゎリズムに埓っお少なくずも同じコヌメンを取る-すべおがそこから番号が付けられおおり、逆にPythonでそれをやり盎すこずは時々䞍䟿です。


さお、速床はどうですか



すべおが始たった理由を思い出す時が来たした。



泚Pythonを忘れおしたったので、コメントに改善点を曞いおください。ラップトップで実行しおランタむムを確認したす。



したがっお、マむクロベンチマヌクを䜿甚した2぀の小さな䟋です。



ベクトル化されたもの
タスク0ず1のベクトルXが関数の入力に䟛絊され、1ず-11-> 1、0-> -1のベクトルに倉換し、このベクトルのフヌリ゚倉換からの係数の数を蚈算する必芁がありたす。絶察倀が境界の境界を超えおいたす。



 def process_fft(x, boundary): return np.count_nonzero(np.abs(np.fft.fft(2*x-1)) > boundary) %timeit process_fft(x, 2000) 84.1 ms ± 335 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
      
      





 function process_fft(x, boundary) count(t -> t > boundary, abs.(fft(2*x.-1))) end @benchmark process_fft(x, 2000) BenchmarkTools.Trial: memory estimate: 106.81 MiB allocs estimate: 61 -------------- minimum time: 80.233 ms (4.75% GC) median time: 80.746 ms (4.70% GC) mean time: 85.000 ms (8.67% GC) maximum time: 205.831 ms (52.27% GC) -------------- samples: 59 evals/sample: 1
      
      





ここでは驚くべきこずは䜕も衚瀺されたせん。同じように、圌ら自身はそれを考慮せず、最適化されたFortranプログラムに枡したす。



ベクトル化できないもの
0ず1の配列が入力され、連続するナニットの最も長いサブシヌケンスの長さを芋぀けたす。



 def longest(x): maxLen = 0 currLen = 0 # This will count the number of ones in the block for bit in x: if bit == 1: currLen += 1 maxLen = max(maxLen, currLen) else: maxLen = max(maxLen, currLen) currLen = 0 return max(maxLen, currLen) %timeit longest(x) 599 ms ± 639 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
      
      





 function longest(x) maxLen = 0 currLen = 0 # This will count the number of ones in the block for bit in x if bit == 1 currLen += 1 maxLen = max(maxLen, currLen) else maxLen = max(maxLen, currLen) currLen = 0 end end return max(maxLen, currLen) end @benchmark longest(x) BenchmarkTools.Trial: memory estimate: 0 bytes allocs estimate: 0 -------------- minimum time: 9.094 ms (0.00% GC) median time: 9.248 ms (0.00% GC) mean time: 9.319 ms (0.00% GC) maximum time: 12.177 ms (0.00% GC) -------------- samples: 536 evals/sample: 1
      
      





違いは肉県で明らかです。 numpyバヌゞョンを「仕䞊げ」および/たたはベクトル化するためのヒントは倧歓迎です。 たた、これらのプログラムはほずんど同じです。 たずえば、ゞュリアに単䞀のタむプを登録したせんでした前のタむプず比范しおください-すべお同じで、すべおが迅速に機胜したす。



たた、提瀺されたバヌゞョンは最終プログラムには含たれおいたせんが、さらに最適化されおいるこずに泚意しおください。 ここでは、それらは䟋ずしお䞎えられおおり、䞍必芁な耇雑さはありたせんJuliaで远加メモリを転送しおrfftをむンプレヌスで実行するなど。



最埌に䜕が出たしたか



PythonずJuliaの最終的なコヌドは衚瀺したせん。これは秘密です少なくずも今のずころ。 Pythonバヌゞョンを終了するために停止した時点で、16メガバむトのバむナリ文字の配列に察するすべおのNISTテストが玄50秒で完了したした。 珟時点のゞュリアでは、すべおのテストが同じボリュヌムで実行されたす最倧20秒。 私は愚か者であり、最適化などの䜙地があったのかもしれたせん。 など しかし、これは私ず同じように、すべおの長所ず短所があり、私の意芋では、プログラミング蚀語の真空䞭のプログラムの球面速床ではなく、私が個人的にどのようにプログラムするこずができるかを考慮する必芁がありたす本圓に重倧な゚ラヌなしに。



なぜこれをすべお曞いたのですか



ここの人々は興味を持ちたした。 時間が来たら曞くこずにしたした。 将来的には、いく぀かの兞型的な問題を解決する䟋を挙げお、ゞュリアをより培底的に怜蚎しおいきたいず思いたす。 なんで より倚くの蚀語、良いもの、異なるもの、そしお自分に合ったものを芋぀けたい人は誰でも聞かせおください。



All Articles