コンパイラPython: Numbaの実力

Pythonを高速にする仕掛けの一つに’NUMBA’というモジュールがある。これは配列の計算のためのもモジュールNUMPYで定義された配列に計算を高速にする。NUMPY自体も配列の計算(例えば二つの配列の積)ができるが、配列の計算はもっと沢山ある。そうのような計算をPythonの演算式を使ってやるととてつもなく時間がかかる。そのような計算部分(関数として定義する)をNUMBAで高速にできる。例を示す:


#coding: utf-8

from numba import jit
from numpy import arange
import time

#関数の引数にNUMPY moduleで定義される配列があるとNUMBA
#によってその関数はコンパイルされる。
#デコレータ@jitはNUMBAを適用するか選択する

@jit
def sum2d(arr):
    M, N = arr.shape
    result = 0.0
    for i in range(M):
        for j in range(N):
            result += arr[i, j]
    return result

start = time.time()
a = arange(100000000).reshape(10000, 10000)
print(sum2d(a))
elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")

結果を示す:

    • NUMBAを適用しない場合:
      4999999950000000.0
      elapsed_time:38.96722865104675[sec]
    • NUMBAを適用した場合:
      4999999950000000.0
      elapsed_time:0.7770442962646484[sec]

30倍もの実行速度がえられる。Pythonコンパイラとしては以前に紹介した’pypy’もあるがNumpyを使っている場合はこのNumbaが便利かもしれない。

コンパイラPython:Pypyの実力

久ぶりにPythonの話題である。

インタプリタであるPythonは実行速度が遅い。この遅い原因を回避するためにPython言語で作ったプログラムをコンパイルして実行するPypyというコンパイラがある。どの位の性能があるか試してみた。環境はOSはwindows7で、使ったPythonおよびPypyのヴァージョンは
>>python -V
Python 3.7.6

>>pypy3 -V
Python 3.6.9 (2ad108f17bdb, Apr 07 2020, 03:05:35)
[PyPy 7.3.1 with MSC v.1912 32 bit]

例1:単純な四則計算


import time
start = time.time()

for i in range(100000000): # 10^8
    1 + 1
    1 - 1
    1 * 1
    1 // 1

process_time = time.time() - start
print(process_time)

結果は
Python3.7  4159ms
Pypy  95ms

となり、約40倍の速度向上が見られた。

例2:配列


import time
start = time.time()

A = [i for i in range(10000000)] # 10^7

for i in range(10000000):
    A[i] = 0

process_time = time.time() - start
print(process_time)

結果は
Python3.7  1844ms
Pypy  70ms

となり、約30倍の速度向上が見られた。

 

Pythonでヴォロノイ図を描く

ヴォロノイ(Voronoi)図をPythonを使って描く。

じつはパッケージSciPyにヴォロノイ図を描くモジュールがある。今回はそれを使ってみた。出来上がった図の一例を示す。

 

このパッケージは日本語を含むファイルPath名のファイルを作成できない。これが苦労したところ。

PythonでDBにアクセス

データベース(DB)にアクセスするプログラムをPythonで作ってみた。
藤沢周平の作品(文庫本で読める作品全て)名をデータベース化したものを用意した。目的は

  • 文庫本毎にはどんな作品が収録されているか
  • 作品カテゴリー(江戸市井もの、海坂藩もの、等)による分類
  • 作品の初出情報

である。使ったDB管理プログラムはSQlite。結果を表示する等のグラフィックユーザフェースはwxpythonを使った。

以下は使用時の画面表示の一部である:

初期画面
初期画面
初出分類
初出分類
作品の初出
作品の初出

ボロノイ図を描く(1)

ボロノイ分割を描画するPythonプログラムを考える。

平面のボロノイ分割は三角形をなす任意の三点(母点という)を円周上に持つ円(唯一である)の中心(ボロノイ頂点という)と半径を決めることである。このボロノイ頂点から三角形の各辺の中点を結ぶとボロノイ辺ができる。このボロノイ辺が三つの母点の勢力圏を分割する分割線となる。今回はこの作業をPythonプログラムとして作った。

使ったツールは

パイソン:Python 3.6.4

描画ツール:matplotlib、 inkscape

一例を示す:

ボロノイ図
ボロノイ図

PythonAnywhereを使ってみる

表題にあるPythonAnywhereは手元のコンピュータにPythonインタプリタをインストールしなくともWEB上にあるPythonインタプリタを使ってPythonプログラムを実行し結果をWEBブラウザーに表示するサービスをしている。

このサービスの使い方はここにある。

今回は日本語を含むプログラムを実行した。使ったプログラムは以下のようなものである:

#coding: utf-8
d = { ‘甲’:(‘コウ’,’きのえ’),
‘乙’:(‘オツ’,’きのと’),
‘丙’:(‘ヘイ’,’ひのえ’),
‘丁’:(‘テイ’,’ひのと’),
‘戊’:(‘ボ’,’つちのえ’)}
for key, value in d.items():
print(key, value)

結果の表示は

となり日本語の処理適切にされている。

インストールなしてPythonが使える点は貴重なサービスである。

 

Pythonプログラムの実行(2)

前回の例は簡単すぎてプログラムという印象が少ないと思ったので今回は「繰り返し」を含む問題である。

九九の表を表示する問題。

プログラムは以下のようになる:

#!/usr/local/bin/python
# -*- coding: euc-jp -*-

print “Content-Type: text/html; charset = EUC-JP \n”

print “九九の表 <br>\n”
for i in range(1,10):
    for j in range(1,10):
        print(“%d x %d = %02d ” % (i,j,i*j))
    print “<br>\n”

最初の三行はWEB上でPythonを実行し結果を表示させるためにある。それら以降が本来のPythonプログラム。結果をWEB上で表示させるために改行や空白の処理に工夫がいる。

実行

Pythonプログラムの実行

Pythonプログラムは一般的には手元にあるコンピュータにPythonインタプリタをインストールして使う。

しかしこのWEBサーバには既にPythonを実行できる環境があるのでこの環境を使って簡単なプログラムを走らせてみる。このような手法をCGIと呼ぶ。CGIの説明

注意点

(1)このサーバにインストールされているPythonは

ヴァージョン:2.75

場所:/usr/local/bin/python

(2)このサーバはFreeBSD(Linuxの一種)で動いているのでそのシステムに合ったテキストファイルを作成する必要がある。具体的には、

文字コード:EUC-JP

改行コード:LF

(3)ファイルの拡張子はcgiにする。

そのファイルの属性は705、このファイルを入れるホルダーの属性は755とする。

(4)試したプログラムは

#!/usr/local/bin/python
# -*- coding: euc-jp -*-

print “Content-Type: text/html; charset = EUC-JP \n”
print “Pythonから今日は”

最後の1行がPython固有のprint文である。

(5)出力結果は

実行