Saya perhatikan bahwa aplikasi Python saya jauh lebih lambat ketika menjalankannya python:2-alpine3.6
daripada menjalankannya tanpa Docker di Ubuntu. Saya datang dengan dua perintah benchmark kecil dan ada perbedaan besar yang terlihat antara kedua sistem operasi, baik ketika saya menjalankannya di server Ubuntu, dan ketika saya menggunakan Docker untuk Mac.
$ BENCHMARK="import timeit; print(timeit.timeit('import json; json.dumps(list(range(10000)))', number=5000))"
$ docker run python:2-alpine3.6 python -c $BENCHMARK
7.6094589233
$ docker run python:2-slim python -c $BENCHMARK
4.3410820961
$ docker run python:3-alpine3.6 python -c $BENCHMARK
7.0276606959
$ docker run python:3-slim python -c $BENCHMARK
5.6621271420
Saya juga mencoba 'patokan' berikut, yang tidak menggunakan Python:
$ docker run -ti ubuntu bash
root@6b633e9197cc:/# time $(i=0; while (( i < 9999999 )); do (( i ++
)); done)
real 0m39.053s
user 0m39.050s
sys 0m0.000s
$ docker run -ti alpine sh
/ # apk add --no-cache bash > /dev/null
/ # bash
bash-4.3# time $(i=0; while (( i < 9999999 )); do (( i ++ )); done)
real 1m4.277s
user 1m4.290s
sys 0m0.000s
Apa yang bisa menyebabkan perbedaan ini?
ubuntu
performance
docker
alpine-linux
Underyx
sumber
sumber
Jawaban:
Saya telah menjalankan tolok ukur yang sama seperti yang Anda lakukan, hanya menggunakan Python 3:
menghasilkan perbedaan lebih dari 2 detik:
Alpine menggunakan implementasi berbeda
libc
(pustaka sistem dasar) dari proyek musl ( mirror URL ). Ada banyak perbedaan di antara perpustakaan-perpustakaan itu . Akibatnya, setiap perpustakaan mungkin berkinerja lebih baik dalam kasus penggunaan tertentu.Berikut ini perbedaan strace antara perintah-perintah di atas . Outputnya mulai berbeda dari baris 269. Tentu saja ada alamat yang berbeda dalam memori, tetapi sebaliknya sangat mirip. Sebagian besar waktu jelas dihabiskan menunggu
python
perintah selesai.Setelah memasang
strace
ke kedua kontainer, kita bisa mendapatkan jejak yang lebih menarik (saya telah mengurangi jumlah iterasi dalam benchmark menjadi 10).Misalnya,
glibc
memuat pustaka dengan cara berikut (baris 182):Kode yang sama di
musl
:Saya tidak mengatakan ini adalah perbedaan utama, tetapi mengurangi jumlah operasi I / O di perpustakaan inti mungkin berkontribusi pada kinerja yang lebih baik. Dari diff Anda dapat melihat bahwa mengeksekusi kode Python yang sama dapat menyebabkan panggilan sistem yang sedikit berbeda. Mungkin yang paling penting dapat dilakukan dalam mengoptimalkan kinerja loop. Saya tidak cukup memenuhi syarat untuk menilai apakah masalah kinerja disebabkan oleh alokasi memori atau instruksi lainnya.
glibc
dengan 10 iterasi:musl
dengan 10 iterasi:musl
lebih lambat oleh 0,0028254222124814987 detik. Sebagai perbedaan tumbuh dengan jumlah iterasi, saya berasumsi perbedaannya adalah dalam alokasi memori objek JSON.Jika kami mengurangi tolok ukur hanya untuk mengimpor,
json
kami melihat perbedaannya tidak terlalu besar:Memuat pustaka Python terlihat sebanding. Menghasilkan
list()
menghasilkan perbedaan yang lebih besar:Jelas operasi yang paling mahal adalah
json.dumps()
, yang mungkin menunjukkan perbedaan alokasi memori antara perpustakaan-perpustakaan itu.Melihat lagi patokannya ,
musl
alokasi alokasi memori benar-benar sedikit lebih lambat:Saya tidak yakin apa yang dimaksud dengan "alokasi besar", tetapi
musl
hampir 2 × lebih lambat, yang mungkin menjadi signifikan ketika Anda mengulangi operasi seperti itu ribuan atau jutaan kali.sumber