Python 3のみを使用して、同じベンチマークを実行しました。
$ docker run python:3-alpine3.6 python --version
Python 3.6.2
$ docker run python:3-slim python --version
Python 3.6.2
2秒以上の差が生じる:
$ docker run python:3-slim python -c "$BENCHMARK"
3.6475560404360294
$ docker run python:3-alpine3.6 python -c "$BENCHMARK"
5.834922112524509
Alpineはlibc
、muslプロジェクト(ミラーURL)とは異なる(ベースシステムライブラリ)の実装を使用しています。これらのライブラリには多くの違いがあります。その結果、特定のユースケースで各ライブラリのパフォーマンスが向上する場合があります。
ここだ上で、これらのコマンドの間にstraceのdiffが。出力は269行目とは異なります。もちろん、メモリには異なるアドレスがありますが、それ以外は非常に似ています。ほとんどの時間は、明らかにpython
コマンドが終了するのを待つことに費やされます。
strace
両方のコンテナにインストールすると、より興味深いトレースを取得できます(ベンチマークの反復回数を10回に減らしました)。
たとえばglibc
、次の方法でライブラリをロードしています(行182):
openat(AT_FDCWD, "/usr/local/lib/python3.6", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
getdents(3, /* 205 entries */, 32768) = 6824
getdents(3, /* 0 entries */, 32768) = 0
の同じコードmusl
:
open("/usr/local/lib/python3.6", O_RDONLY|O_DIRECTORY|O_CLOEXEC) = 3
fcntl(3, F_SETFD, FD_CLOEXEC) = 0
getdents64(3, /* 62 entries */, 2048) = 2040
getdents64(3, /* 61 entries */, 2048) = 2024
getdents64(3, /* 60 entries */, 2048) = 2032
getdents64(3, /* 22 entries */, 2048) = 728
getdents64(3, /* 0 entries */, 2048) = 0
これが重要な違いだとは言いませんが、コアライブラリのI / O操作の数を減らすと、パフォーマンスが向上する可能性があります。diffから、まったく同じPythonコードを実行すると、システムコールがわずかに異なる可能性があることがわかります。おそらく、ループパフォーマンスの最適化で最も重要なことができます。パフォーマンスの問題がメモリ割り当てまたは他の命令によって引き起こされているかどうかを判断する資格がありません。
glibc
10回の反復:
write(1, "0.032388824969530106\n", 210.032388824969530106)
musl
10回の反復:
write(1, "0.035214247182011604\n", 210.035214247182011604)
musl
0.0028254222124814987秒遅くなります。繰り返しの数とともに違いが大きくなるにつれて、JSONオブジェクトのメモリ割り当てに違いがあると思います。
ベンチマークをインポートのみに減らすと、json
その差はそれほど大きくないことに気付きます。
$ BENCHMARK="import timeit; print(timeit.timeit('import json;', number=5000))"
$ docker run python:3-slim python -c "$BENCHMARK"
0.03683806210756302
$ docker run python:3-alpine3.6 python -c "$BENCHMARK"
0.038280246779322624
Pythonライブラリのロードは同等に見えます。生成list()
により大きな違いが生じます。
$ BENCHMARK="import timeit; print(timeit.timeit('list(range(10000))', number=5000))"
$ docker run python:3-slim python -c "$BENCHMARK"
0.5666235145181417
$ docker run python:3-alpine3.6 python -c "$BENCHMARK"
0.6885563563555479
明らかに最も高価な操作はjson.dumps()
であり、これらのライブラリ間のメモリ割り当ての違いを示している可能性があります。
再び見るとベンチマーク、
musl
メモリ割り当てにわずかに遅い実際にあります:
musl | glibc
-----------------------+--------+--------+
Tiny allocation & free | 0.005 | 0.002 |
-----------------------+--------+--------+
Big allocation & free | 0.027 | 0.016 |
-----------------------+--------+--------+
「大きな割り当て」が何を意味するのかはわかりませんmusl
が、ほぼ2倍遅くなります。