Optimized Pythonを試す

「python Advent Calendar 2017 10日目」 の記事です。

TwitterのTLをぼーっと眺めていたら気になるサイトを見つけました。

Check This Out – Optimized Python

なんと、このdockerイメージを使うと、公式のPythonのイメージと比較して、19%の高速化と75%の軽量化がされているようです。 これは試さずにはいられません。

ビルドされたイメージは Docker Hub に上がっており、イメージをpullするだけで最適化されたPythonが使えます。

Pythonのバージョンは3.5.4および3.6.3が用意されているようです。 1

イメージのサイズはGitLabやGitHubのREADMEを見る限りだと下記のようになっているようです。

REPOSITORY

TAG

SIZE

python

3.6.3

690MB

python

3.6-slim

201MB

python

3.6.3-alpine

89MB

registry.gitlab.com/revsys/docker-builds/python

3.6.3-wee

153MB

さすがにalpineをベースにしたイメージよりは大きくなっていますが、非常にコンパクトにまとまっています。 Debian 8ベースなので、many linux wheelのパッケージが使えるのが大きな利点です。 ちなみに筆者はalpineベースでイメージを作ったことがありますが、pipインストール時にビルドが必要なパッケージを入れようとして何度も泣いたことがあります(´°̥̥̥̥̥̥̥̥ω°̥̥̥̥̥̥̥̥`)

早速ベンチマークをとってみましょう。筆者のHW環境は下記のとおりです。 2010年くらいのモデルですが未だ現役で使ってます...早くRyzen MobileのPCでないかなぁ...

Architecture:

x86_64

CPU op-mode(s):

32-bit, 64-bit

Byte Order:

Little Endian

CPU(s):

4

On-line CPU(s) list:

0-3

Thread(s) per core:

2

Core(s) per socket:

2

Socket(s):

1

NUMA node(s):

1

Vendor ID:

GenuineIntel

CPU family:

6

Model:

37

Model name:

Intel(R) Core(TM) i5 CPU M 520 @ 2.40GHz

Stepping:

5

CPU MHz:

1333.000

CPU max MHz:

2400.0000

CPU min MHz:

1199.0000

BogoMIPS:

4788.43

Virtualization:

VT-x

L1d cache:

32K

L1i cache:

32K

L2 cache:

256K

L3 cache:

3072K

NUMA node0 CPU(s):

0-3

下記の3つのパターンでベンチマークしています、ベンチマークには pyperformance というライブラリを使いました。

  • 公式のPythonイメージ: python:3.6.3

  • Optimized Pythonイメージ: python:3.6.3-wee-optimized-lto

  • OSのPython3.6.3: Ubuntu 17.10

結果は下記のとおりです。

Benchmark

docker

docker optimized

system

2to3

1.09 sec

954 ms: 1.15x faster (-13%)

1.21 sec: 1.10x slower (+10%)

chameleon

39.7 ms

30.4 ms: 1.31x faster (-23%)

34.7 ms: 1.14x faster (-12%)

chaos

414 ms

355 ms: 1.17x faster (-14%)

350 ms: 1.18x faster (-15%)

crypto_pyaes

310 ms

281 ms: 1.10x faster (-9%)

283 ms: 1.09x faster (-9%)

deltablue

25.7 ms

21.4 ms: 1.20x faster (-17%)

21.7 ms: 1.18x faster (-15%)

django_template

617 ms

490 ms: 1.26x faster (-21%)

531 ms: 1.16x faster (-14%)

fannkuch

1.38 sec

1.23 sec: 1.12x faster (-11%)

1.25 sec: 1.10x faster (-9%)

float

328 ms

309 ms: 1.06x faster (-6%)

305 ms: 1.08x faster (-7%)

genshi_text

121 ms

103 ms: 1.17x faster (-15%)

109 ms: 1.11x faster (-10%)

genshi_xml

268 ms

223 ms: 1.21x faster (-17%)

240 ms: 1.12x faster (-11%)

go

846 ms

717 ms: 1.18x faster (-15%)

741 ms: 1.14x faster (-12%)

hexiom

32.9 ms

27.8 ms: 1.18x faster (-16%)

29.9 ms: 1.10x faster (-9%)

html5lib

343 ms

290 ms: 1.18x faster (-16%)

306 ms: 1.12x faster (-11%)

json_dumps

40.3 ms

34.5 ms: 1.17x faster (-14%)

37.2 ms: 1.08x faster (-8%)

json_loads

79.3 us

66.0 us: 1.20x faster (-17%)

72.4 us: 1.10x faster (-9%)

logging_format

47.8 us

38.9 us: 1.23x faster (-19%)

41.0 us: 1.17x faster (-14%)

logging_silent

1.02 us

936 ns: 1.09x faster (-9%)

909 ns: 1.13x faster (-11%)

logging_simple

39.4 us

32.1 us: 1.22x faster (-18%)

34.4 us: 1.14x faster (-13%)

mako

63.0 ms

51.6 ms: 1.22x faster (-18%)

54.5 ms: 1.16x faster (-14%)

meteor_contest

278 ms

237 ms: 1.17x faster (-15%)

248 ms: 1.12x faster (-11%)

nbody

304 ms

329 ms: 1.08x slower (+8%)

281 ms: 1.08x faster (-7%)

nqueens

355 ms

318 ms: 1.11x faster (-10%)

311 ms: 1.14x faster (-12%)

pathlib

84.3 ms

64.6 ms: 1.30x faster (-23%)

62.2 ms: 1.35x faster (-26%)

pickle

32.0 us

26.1 us: 1.23x faster (-18%)

26.8 us: 1.20x faster (-16%)

pickle_dict

78.2 us

66.5 us: 1.18x faster (-15%)

58.0 us: 1.35x faster (-26%)

pickle_list

10.7 us

8.90 us: 1.21x faster (-17%)

8.75 us: 1.23x faster (-19%)

pickle_pure_python

1.81 ms

1.60 ms: 1.14x faster (-12%)

1.63 ms: 1.11x faster (-10%)

pidigits

378 ms

not significant

368 ms: 1.03x faster (-3%)

python_startup

30.4 ms

27.6 ms: 1.10x faster (-9%)

27.7 ms: 1.10x faster (-9%)

python_startup_no_site

20.8 ms

19.3 ms: 1.08x faster (-7%)

18.8 ms: 1.11x faster (-10%)

raytrace

1.94 sec

1.66 sec: 1.17x faster (-15%)

1.63 sec: 1.19x faster (-16%)

regex_compile

630 ms

529 ms: 1.19x faster (-16%)

568 ms: 1.11x faster (-10%)

regex_dna

365 ms

340 ms: 1.07x faster (-7%)

355 ms: 1.03x faster (-3%)

regex_effbot

6.34 ms

6.18 ms: 1.03x faster (-3%)

6.10 ms: 1.04x faster (-4%)

regex_v8

60.5 ms

54.2 ms: 1.12x faster (-10%)

55.2 ms: 1.10x faster (-9%)

richards

264 ms

231 ms: 1.14x faster (-12%)

235 ms: 1.12x faster (-11%)

scimark_fft

908 ms

939 ms: 1.03x slower (+3%)

805 ms: 1.13x faster (-11%)

scimark_lu

691 ms

594 ms: 1.16x faster (-14%)

not significant

scimark_monte_carlo

387 ms

328 ms: 1.18x faster (-15%)

325 ms: 1.19x faster (-16%)

scimark_sor

717 ms

604 ms: 1.19x faster (-16%)

669 ms: 1.07x faster (-7%)

scimark_sparse_mat_mult

11.7 ms

not significant

9.74 ms: 1.20x faster (-17%)

spectral_norm

339 ms

329 ms: 1.03x faster (-3%)

328 ms: 1.03x faster (-3%)

sqlalchemy_declarative

440 ms

406 ms: 1.08x faster (-8%)

394 ms: 1.12x faster (-10%)

sqlalchemy_imperative

90.9 ms

80.4 ms: 1.13x faster (-12%)

82.5 ms: 1.10x faster (-9%)

sqlite_synth

12.6 us

11.1 us: 1.14x faster (-12%)

10.4 us: 1.21x faster (-18%)

sympy_expand

1.55 sec

1.27 sec: 1.22x faster (-18%)

1.34 sec: 1.16x faster (-13%)

sympy_integrate

66.7 ms

55.0 ms: 1.21x faster (-17%)

58.7 ms: 1.14x faster (-12%)

sympy_sum

313 ms

259 ms: 1.21x faster (-17%)

275 ms: 1.14x faster (-12%)

sympy_str

689 ms

569 ms: 1.21x faster (-17%)

598 ms: 1.15x faster (-13%)

telco

29.0 ms

21.1 ms: 1.37x faster (-27%)

25.6 ms: 1.13x faster (-12%)

tornado_http

612 ms

527 ms: 1.16x faster (-14%)

549 ms: 1.12x faster (-10%)

unpack_sequence

143 ns

139 ns: 1.03x faster (-3%)

139 ns: 1.03x faster (-3%)

unpickle

43.1 us

38.0 us: 1.13x faster (-12%)

37.1 us: 1.16x faster (-14%)

unpickle_list

8.95 us

7.90 us: 1.13x faster (-12%)

not significant

unpickle_pure_python

1.20 ms

1.07 ms: 1.11x faster (-10%)

1.14 ms: 1.05x faster (-5%)

xml_etree_parse

379 ms

343 ms: 1.10x faster (-9%)

390 ms: 1.03x slower (+3%)

xml_etree_iterparse

329 ms

292 ms: 1.13x faster (-11%)

301 ms: 1.09x faster (-8%)

xml_etree_generate

387 ms

308 ms: 1.25x faster (-20%)

350 ms: 1.11x faster (-10%)

xml_etree_process

338 ms

263 ms: 1.28x faster (-22%)

290 ms: 1.16x faster (-14%)

Optimized Pythonは上記のどの項目においても公式のPythonイメージより高速に動作することがわかりました。 ただ、システム(OS)のPythonとほぼ同じような速度なので、元からシステムのPythonを使ってる場合には恩恵はなさそうです。

既にDockerでPythonを使っており、下記のような記述の場合は

FROM python:3.6.3

下記のように書き換えるだけでPythonの処理が高速になる可能性があります。

FROM revolutionsystems/python:3.6.3-wee-optimized-lto

DockerでPythonを使っていて、少しでも高速化したい場合には試してみてはいかがでしょうか。

Footnotes

1

2017年12月1日現在、最新情報はDocker Hubのタグを参照 https://hub.docker.com/r/revolutionsystems/python/tags/