182
172

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonの実行を高速化する方法を䞀芧でたずめおみた

182
Last updated at Posted at 2022-02-11

はじめに

Pythonは最近ずおも人気で、機械孊習だけでなく様々な分野で幅広く䜿われおいたす。
しかし、Pythonには実行速床が遅いずいう匱点がありたす。
高速なC蚀語などず比べお数癟倍遅く、科孊蚈算などでは残念ながらPythonは遞択肢に入りたせん。
しかし私はPythonが奜きで、{}やendを曞いたり、いちいち倉数宣蚀なんおしたくないので、高速化する方法を調べたした。

調べおみたずころ、Pythonを高速化する䞀぀䞀぀の方法の詳しい解説蚘事は芋぀かりたした。
しかし、網矅するような逆匕きのたずめがなかったので、蚘事を曞くこずにしたした。

それぞれの方法を調べたしたが、実際に䜿甚したこずがないものが倚いため、蚘事で間違いがありたしたら、ぜひ指摘しおください。
たた、ここに茉っおいない高速化方法などありたしたら、ぜひコメント欄で教えおください。
よろしくお願いしたす。

目次

曞いた内容は、芏暡が倧きい順に䞊べたした。

項番 項目 抂芁
1 1. クラスタレベル 耇数コンピュヌタを぀なげお分散凊理する方法
2 2. コンピュヌタレベル 単䞀PC内で高速化する方法
3 3. Python凊理系、コンパむラレベル 特定のPythonの皮類、コンパむラを䜿甚しお高速化する方法
4 4. Pythonラむブラリレベル 高速なラむブラリを䜿甚する方法
5 5. コヌディングレベル 高速に動䜜するようなコヌドを曞く方法
6 6. 番倖線高速な他蚀語のプログラムを呌び出す 他の高速な蚀語を䜿甚する方法
7 7. 番倖線2ハヌドりェアの遞択 CPUやGPUなどハヌドりェアの遞び方

1. クラスタレベル

耇数のマシンを䜿甚するクラスタレベルで分散凊理するこずで高速化する方法です。
もうここたでくるず Python ずいうプログラミング蚀語レベルではなくなりたすが、高速化の遞択肢ずしお説明したす。

Hadoop

倧量のデヌタを耇数マシンに分散しお凊理させるオヌプン゜ヌスのプラットフォヌム。
Google瀟内基盀技術をオヌプン゜ヌスずしお実装したものらしいです。

Apache Spark

カリフォルニア倧孊バヌクレヌ校で開発された分散凊理フレヌムワヌク。
Hadoopよりもメモリをうたく䜿うこずで、機械孊習を高速で実行できるようにしたものです。

2. コンピュヌタレベル

1台のコンピュヌタの䞭で高速化する方法です。
高速化のアプロヌチずしおは、䞊列化、GPGPUの遞択がありたす。

2-1. 䞊列化

䞀぀のマシンの䞭で、プログラムを䞊列化しお実行しお高速化する方法です。

詳しくは東京倧孊の情報基盀センタヌが無料で公開しおいる動画がわかりやすいです。

ちなみに䞊行凊理ず䞊列凊理がありたすが、違いは詳しくはクリック

Pythonラむブラリを䜿甚した䞊列化

Pythonのプログラムは、ラむブラリを䜿甚するこずで比范的簡単にできたす。
ラむブラリずしお、multiprocessing、threading、concurrent.futuresなどがありたす。
マルチプロセス、マルチスレッドを䞀緒に玹介しおいる蚘事が倚いので、区別せずにリンクを貌りたす。

MPI

分散メモリ型蚈算機の プロセス間 の通信芏栌らしい。
スパコンで䞊列凊理するために䜿甚されるこずが倚い。

詳しくは東京倧孊の情報基盀センタヌが無料で公開しおいる動画がわかりやすいです。

いわゆる マルチプロセス
もずもずC、C++、Fortranから呌び出すものだが、Pythonからもmpi4pyずいうラむブラリを䜿甚するこずで利甚できる。

座孊「䞊列プログラミング入門」in 金沢 第2講 䞊列凊理ずMPIの基瀎
座孊「䞊列プログラミング入門」in 金沢 第4講 Hybrid䞊列化技法MPIずOpenMPの応甚PDF
名叀屋倧孊情報基盀センタヌ MPIの基瀎
東京倧孊情報基盀センタヌ MPI基瀎䞊列プログラミング入門
神戞倧孊蚈算科孊教育センタヌ MPIによる䞊列化実装

OpenMP

共有メモリ型マシンで䞊列プログラミングを可胜にするAPIです。スパコンでよく䜿われたす。
いわゆる マルチスレッド
C、C++、Fortranに぀いお暙準化が行われおいたす。
Cython経由でOpenMPを䜿甚できるらしいですが、Pythonではあたり実甚的ではなさそうです。

座孊「䞊列プログラミング入門」in 金沢 第3講 OpenMPの基瀎PDF
座孊「䞊列プログラミング入門」in 金沢 第4講 Hybrid䞊列化技法MPIずOpenMPの応甚PDF
名叀屋倧孊情報基盀センタヌ OpenMPの基瀎
理化孊研究所 OpenMPによるスレッド䞊列蚈算

2-2. GPGPU

GPGPUずは、General Purpose GPUの略で、GPUを画像凊理以倖に䜿甚する技術です。ディヌプラヌニングやマむニングに䜿甚されおいるのが有名です。
GPUは汎甚性がCPUず比べお䜎いですが、行列蚈算などがずおも高速です。
そのため、GPUを凊理の䞀郚で䜿甚するこずで高速化が可胜です。
ただし、メモリ䞊にある配列をGPUのメモリに移しお、蚈算埌に戻すために時間がかかるため、堎合によっおはより時間がかかっおしたうこずもありたす。

CuPy

NumPy互換のむンタヌフェヌスを持ち、GPUを䜿うこずができるラむブラリです。
日本のベンチャヌ䌁業Preferred Networksが開発したした。Chainerを䜜っおいた䌚瀟
おそらく䞀番䜿いやすくお有名です。
倉数は明瀺的にプログラムでメモリ-GPU間を移動させる必芁がありたす。

TensorFlow

ディヌプラヌニング界の2倧フレヌムワヌクの片割れです。
ディヌプラヌニング自䜓テン゜ル同士の挔算行列同士の挔算であるため、ディヌプラヌニング以倖にも䜿甚可胜です。
GPUずCPUを䜿い分けるこずを前提にしお蚭蚈されおいるため、メモリ-GPU間の倉数の移動を自動で行っおくれたす。
ただしディヌプラヌニング以倖で䜿甚しおいるのをみたこずがないので、情報が少なく孊習が倧倉かもしれたせん。

PyCUDA

本来C/C++で䜿甚するCUDAを、Pythonから呌び出せるようにバむンディングしたラむブラリです。
おそらくCUDAに関する知識がないず䜿えなさそうです。
そしおネット䞊にあたり情報がないです。

Numba.cuda

埌に解説するNumbaずいうラむブラリにCUDAを䜿甚するものが含たれおいるらしいです。
おそらくCUDAに関する知識がないず䜿えなさそうです。
ネット䞊にあたり情報がない。

3. Python凊理系、コンパむラレベル

普通のPythonはCPythonずいっお、C蚀語で曞かれた凊理系らしいです。
しかし他にもJavaで実装されたJython、C#で実装されたIronPythonがあったり、JITコンパむラによっおコンパむルを最適化しお高速化しおくれるものがりたす。
この章では、高速化しおくれる凊理系、コンパむラに関しおたずめたした。

↑のサむトに比范したものがわかりやすくたずめられおいたすが、
軜くたずめるず実行速床は
C++ > 越えられない壁 > Codon > Numba > Cython > PyPy > Cpython(デフォ)
のようです。
たた、私芋ですが、元のコヌドをどれだけ曞き換えないで枈むかで比范するず、
Cpython(デフォ) > PyPy(曞き換え䞍芁) > Numba(関数の前に@jitを曞くだけ) > Codon(型ヒントを远加) > Cython(独特の型宣蚀や関数定矩) > 超えられない壁 > C++(別蚀語)
ずいったような状況のようです。

3-1. 凊理系

PyPy

CPythonを制限したRPythonで実装されたPython凊理系で、か぀JITコンパむルをするものらしいです。
競プロでよく䜿われるみたいですが、PyPyに぀いお説明したwebサむトが少ないです。

3-2. コンパむラ

Numba

比范的簡単に高速化できる方法が、Numbaラむブラリを䜿甚するこずです。
コヌドを最適化しお事前にコンパむルするこずで、数十倍速くなるこずもあるそうです。
コヌドをほが曞き換えずに正確には、むンポヌトしお関数の前にデコレヌタを付け足すなどしお高速化するこずができたす。

Cython

Pythonが遅いならPythonのコヌドをcに倉換しおコンパむルしたおうずいう発想。
C蚀語になるので、ずおも高速ちゃんず曞けば100倍になりたすが、Pythonコヌド内で型宣蚀をする必芁があるみたいです。
Numbaず比べお、C蚀語の動䜜環境を䜜ったりず導入たでがめんどくさそうです。

Codon

ほがPythonのコヌドで、コンパむル時にネむティブなマシンコヌドにするこずで高速化を実珟した新しいコンパむラです。
新しいのでただ情報が党然ありたせん。

4. Pythonラむブラリレベル

Pythonプログラム内で䜿甚するこずで高速化に぀ながるラむブラリを玹介したす。

NumPy

C蚀語ずFortranで曞かれた、高速に配列行列の蚈算をするラむブラリです。
非垞に有名で、しょっちゅう出おきたす。
ただし、numpy.arrayをforルヌプで回すず遅くなるなどの萜ずし穎があるみたいなので泚意したしょう。

20220914远蚘

numpyは裏でBLASを呌び出しおいるらしいですが、このBLASの皮類によっお蚈算速床が異なるそうです。
最速はintel補のIntel MKLで、condaでnumpyをむンストヌルするずこれが入っおいたすが、pipでむンストヌルするずOpenBLASが䜿甚され、遅くなっおしたうそうです。
どちらのBLASが入っおいるかは以䞋のようにしお確認できたす。

import numpy as np
np.__config__.show()

pickle

デヌタの読み蟌む際に、pickleを䜿甚するず速くなりたす。
pickleはPythonオブゞェクトをバむナリファむルにするPickle 化をするラむブラリで、Python以倖では読み蟌めたせんが、ずおも高速に十数倍読み蟌むこずができるずいうメリットがありたす。

5. コヌディングレベル

Pythonのプログラムの曞き方次第で高速化できる方法はたくさんありたす。
この章では、Pythonの理解、アルゎリズム、メモリの理解に぀いおたずめたす。

5-1. Pythonの理解

Python特有の高速化方法がありたす。
䟋えば、内包衚蚘や、importの方法に぀いおです。

5-2. アルゎリズム

アルゎリズムは、Pythonだけでなく、すべおのプログラムに通甚する基本的な考え方です。
アルゎリズムの速床の指暙ずしお、$O(n^2)$ や $O(n\log{n})$ や $O(2^n)$ ずいった蚈算量オヌダヌを䜿甚したす。
アルゎリズムには、探玢、゜ヌト、最適化などさたざたな皮類があり、それぞれにさたざたなアルゎリズムが存圚したすが、玹介しきれないのでたずめお玹介したす。

䞖界的なアルゎリズムのバむブル The Art of Computer ProgrammingAmazon

5-3. メモリの理解

プログラムが配列をメモリに栌玍する方法は、Row-major order方匏ずColumn-major order方匏がありたす。
Python(numpy)はRow-major order方匏なので、2次元なら(A[0][0], A[0][1], A[0][2], A[1][0], ...ずいう順に、3次元なら[k,j,i]順にアクセスするず速いそうです。

高速化に぀いお

座孊「䞊列プログラミング入門」in 金沢 第1講 プログラム高速化の基瀎PDF

メモリ栌玍に぀いお

名叀屋倧孊情報基盀センタヌ MPIの基瀎

高性胜プログラミングⅠ入門線

6. 番倖線高速な他蚀語のプログラムを呌び出す

ここたで基本的にPythonに぀いおの高速化の方法をたずめおきたした。
この章では、「Pythonが遅い蚀語なら、他のの高速な蚀語で曞いたプログラムを呌び出しお䜿えばいいじゃん」ずいう発想のもず、その方法をたずめたす。
今回は、有名な高速な蚀語ずしお、Fortran, C, C++, juliaに぀いおたずめたした。

6-1. Fortran

ctypesを䜿甚する方法ず、f2pyを䜿甚する方法がある。

6-2. C

どうやらCでラッパヌを䜜る方法ず、ctypesラむブラリを䜿うの二皮類があるらしい
ちょっず私の理解䞍足で、うたく説明できたせんでした。

ラッパヌ

ctypes

6-3. C++

どうやらpybind11ラむブラリを䜿う方法ず、swigを䜿う方法があるらしい。

6-4. julia

7. ハヌドりェアの遞択

プログラムを実行しおいるのはコンピュヌタです。
ならば、スペックの高いコンピュヌタを䜿甚すれば実行速床は速くなりたす。
ずいっおも、盞圓なこずものすごいボトルネックの解消などがない限り数倍の高速化などにはならないず思いたす。
スペックの高いコンピュヌタ に぀いおたずめおいきたす。

PCパヌツ党䜓

OS

正確には゜フトりェアですが、パ゜コンを買うずきに決たるようなものなのでここで玹介したす。
有名なOSずいえばwindowsずlinuxでしょう。
機械孊習はlinuxのほうがwindowよりも倍ぐらい速いみたいです。
他の普通のプログラムはlinuxのほうがwindowよりもほんのちょっず速いみたいですが、倧した差がないみたいです。

CPU

CPUで重芁になっおくる芁玠は動䜜呚波数、コア数䞊列数、キャッシュの3぀です。

動䜜呚波数は高ければ高いほど1秒間に挔算できる回数が増え、プログラムの実行速床向䞊が芋蟌めたす。さらに、CPIず蚀っお䞀呜什数圓たりにかかるクロック数の数も䞖代がた぀に぀れお向䞊しおいるようですが、正盎プログラムが早くなるかは内容によるのでなんずも蚀えなさそうです。

コア数は䞊列凊理をする堎合、効いおきたす
これはプログラムが䞊列凊理に察応しおいるか、䞊列凊理が効きやすいプログラム化で倉わっおきたす。

キャッシュは、メモリからデヌタをずっおくる代わりにCPUに近いキャッシュにデヌタを眮いおおくずいうものであり、AMDがRyzen5800X3Dなどのようにゲヌム向けにキャッシュを増やしたCPUを販売しおいたすが、プログラムで改善が望めるかはわかりたせん。

いろいろ曞きたしたが、基本的に䞖代が新しくお動䜜呚波数が高いものを買えばよさそうです。
ただし䞊列化するならコア数、スレッド数が倚いものを買うずいいです。

GPU

GPGPUや、ディヌプラヌニングをするなら䞀番重芁です。
GPUで重芁になっおくるこずは、挔算性胜ずメモリ、ディヌプラヌニング甚のコアがあるかなどでしょう。

挔算性胜は、1秒間に浮動小数点挔算が䜕回できるかずいう指暙であり、コアの数が倧きいほど倧きくなる傟向があり、基本的にはGPUの性胜はこれで枬りたす。

メモリに぀いお、特に近幎のディヌプラヌニングではモデルのサむズがどんどん倧きくなっおおり、メモリの倧きさ次第で実行できるプログラムも倉わっおくるため重芁になっおきおいたす。

ディヌプラヌニング専甚のコアを搭茉するGPUも出おきおおり、NvidiaならRTコア、AppleならNeural Engineなどがありたす。

メモリ

プログラム実行時にメモリをたくさん䜿うなら、メモリ容量を十分確保する必芁がありたす。
たた、動䜜呚波数や転送速床なども皮類がありたすが、詳しくは觊れたせん。

ストレヌゞHDD、SSD

保存したデヌタの読み出し、デヌタの曞き蟌みに時間がかかっおいるなら、SSDの䞭でも高速なものにするこずで高速化が芋蟌めたす。
SSDずいっおもさらに普通のSATA接続のものから高速なNVMeSSD、さらにNVMeSSDの䞭でもgen4、gen5など䞖代がありたす。

最埌に

Pythonの実行を高速化する方法をたずめたした。
思った以䞊に様々な方法があり、たた芏暡も党然違うため、分類しおたずめるのが倧倉でした。
しかし曞き終わっおみるず、かなり高速化に぀いお浅く広い知識が付きたした。
それぞれのプログラムにあった高速化方法があるず思うので、ぜひ逆匕きずしお䜿甚しおください。

たた、䜕か間違い、他の高速化方法などありたしたら、遠慮なくコメントしおください。
よろしくお願いしたす。

その他参考になったサむト

182
172
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
182
172

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?