Saya mengevaluasi ekspresi 6^6^6
menggunakan python
dan bc
secara terpisah.
Isi dari file python adalah print 6**6**6
. Ketika saya mengeksekusi time python test.py
, saya mendapatkan output sebagai
real 0m0.067s
user 0m0.050s
sys 0m0.011s
Dan kemudian, saya menjalankan perintah time echo 6^6^6 | bc
yang memberi saya output berikut
real 0m0.205s
user 0m0.197s
sys 0m0.005s
Dari hasil ini jelas bahwa waktu sistem yang diambil oleh python dan bc adalah 11ms dan 5ms masing-masing. The perintah bc mengungguli python di tingkat saat sys tetapi ketika datang ke pengguna dan real time python hampir 4 kali lebih cepat dari bc . Apa yang mungkin terjadi di sana. Saya belum memberikan prioritas pada prosesnya. Saya mencoba memahami situasi ini.
python
performance
process-management
bc
Ganessh
sumber
sumber
echo | bc
melibatkan meluncurkan subkulit karena pipa - di situlah sebagian waktu pengguna tambahan Anda mungkin berasal. Untuk membuat ini menjadi uji yang adil, skrip python harus membaca dari stdin sehingga Anda bisatime echo 6**6**6 | whatever.py
.echo 6^6^6 | time bc
.6**6**6
ekspresi sebenarnya dihitung pada waktu kompilasi . Namun karena Anda meluncurkan file secara langsung alih-alih mengimpornya dari modul, ini tidak masalah. Untuk melihat perbedaan yang dimasukkan10**12345678
ke dalama.py
file dan mencoba mengimpornya dari juru bahasa interaktif. Kemudian tutup penerjemah, mulai ulang dan impora
lagi. Pertama kali harus mengambil jumlah waktu yang nyata (karena python menyusun modul), sedangkan yang kedua memuat.pyc
, yang harus seketika,Jawaban:
Python mengimpor sejumlah besar file pada saat startup:
Masing-masing membutuhkan lebih banyak upaya membuka file Python, karena ada banyak cara untuk mendefinisikan modul:
Setiap "mencoba", kecuali yang sudah dibangun, membutuhkan os-level / system calls, dan setiap "impor" tampaknya memicu sekitar 8 pesan "mencoba". (Ada cara untuk mengurangi ini menggunakan zipimport, dan setiap jalur di PYTHONPATH Anda mungkin memerlukan panggilan lain.)
Ini berarti ada hampir 200 panggilan sistem stat sebelum Python dimulai pada mesin saya, dan "waktu" menetapkan itu untuk "sys" daripada "pengguna", karena program pengguna menunggu pada sistem untuk melakukan sesuatu.
Sebagai perbandingan, dan seperti kata terdon, "bc" tidak memiliki biaya startup yang tinggi. Melihat output dtruss (saya punya Mac; "strace" untuk OS berbasis Linux), saya melihat bahwa bc tidak membuat panggilan sistem terbuka () atau stat () sendiri, kecuali untuk memuat beberapa yang dibagi perpustakaan adalah awal, yang tentu saja Python juga. Selain itu, Python memiliki lebih banyak file untuk dibaca, sebelum siap untuk memproses apa pun.
Menunggu disk lambat.
Anda dapat memahami biaya startup Python dengan melakukan:
Ini 0,032 di komputer saya, sedangkan 'cetak 6 ** 6 ** 6' adalah 0,072, jadi biaya awal adalah 1/2 dari keseluruhan waktu dan perhitungan + konversi ke desimal adalah setengahnya. Sementara:
membutuhkan 0,005s, dan "6 ^ 6 ^ 6" membutuhkan 0,184s sehingga eksponensial bc lebih dari 4x lebih lambat dari Python walaupun itu 7x lebih cepat untuk memulai.
sumber
Saya menemukan jawaban yang bagus pada SO menjelaskan berbagai bidang:
Jadi, dalam contoh spesifik Anda, versi python lebih cepat dalam hal waktu aktual yang diperlukan untuk menyelesaikannya. Namun, pendekatan python menghabiskan lebih banyak waktu di ruang kernel, membuat panggilan ke fungsi kernel. The
bc
perintah menghabiskan dasarnya tidak ada waktu dalam ruang kernel dan semua waktu yang dihabiskan di user-space, mungkin menjalankan internal yangbc
kode.Ini tidak ada bedanya bagi Anda, satu-satunya informasi yang benar-benar Anda pedulikan adalah
real
waktu aktual yang berlalu antara meluncurkan perintah dan mendapatkan outputnya.Anda juga harus menyadari bahwa perbedaan kecil ini tidak stabil, mereka juga akan tergantung pada beban sistem Anda dan akan berubah setiap kali Anda menjalankan perintah:
sumber
Saya akan menjelaskannya dari perspektif lain.
Agar adil,
bc
memiliki keuntungan karena tidak harus membaca apa pun dari disk dan hanya perlu blob / binari-nya sementara python harus mengimpor serangkaian modul + membaca file. Jadi tes Anda mungkin biasbc
. Untuk benar-benar mengujinya, Anda harus menggunakanbc -q file
tempat yangfile
berisi:Mengubah hal itu mengubah waktu penggunaan
echo
:Untuk menggunakan file:
(Anda harus menggunakan metode terdon untuk melihat perbedaan yang lebih besar, tetapi setidaknya kita tahu itu)
Sekarang, dari perspektif python, python perlu membaca dari disk, mengkompilasi dan mengeksekusi setiap kali file, ditambah memuat modul sebagai poin Andrew , yang membuat waktu eksekusi lebih lambat. Jika Anda mengkompilasi kode byte skrip python, Anda akan melihat bahwa dibutuhkan 50% lebih sedikit waktu total untuk mengeksekusi kode:
dikompilasi:
Seperti yang Anda lihat, ada beberapa faktor yang dapat mempengaruhi waktu eksekusi antara berbagai alat.
sumber
Saya mendapat manfaat dari membaca jawaban lain. Sebagai permulaan, orang-orang seperti saya harus tahu alasan mengapa kita berurusan dengan bilangan bulat yang sangat besar di sini adalah karena keduanya
Python
danbc
melakukan ekspansi eksponensial asosiatif yang benar, yang berarti bahwa ini bukan6^36
kita sedang mengevaluasi tetapi lebih tepatnya6^46656
yang jauh lebih besar. 1Menggunakan variasi pada perintah berikut, kita dapat mengekstrak rata-rata untuk elemen spesifik dari output
time
kata dan perintah yang dipesan:Dimungkinkan untuk memilih rute lain dan menghapus file sepenuhnya dari perbandingan. Juga, kita dapat membandingkan waktu bc dengan sesuatu seperti
dc
perintah, karena secara historis yang pertama adalah "prosesor ujung depan" ke yang terakhir. Perintah berikut diberi batas waktu:Perhatikan bahwa
dc
perintah tersebut adalah asosiatif kiri untuk eksponensial. 2Kami memiliki beberapa hasil dengan
time
(bash) untuk 1000 iterasi (dalam detik):bc
dandc
menawarkan kinerja yang sebanding dalam konteks ini.Kurang akurat 3 hasil dari perintah
/usr/bin/time
GNU yaitutime
(skala presisi tidak valid di sini tetapi hasilnya serupa):Keuntungannya
/usr/bin/time
adalah ia menawarkan-v
opsi yang menghasilkan lebih banyak informasi yang akhirnya berguna.Dimungkinkan juga untuk mengevaluasi ini secara internal sehingga dapat berbicara dengan
timeit
modul Python:Itu sedikit lebih cepat dari yang kita lihat sebelumnya. Mari kita coba penerjemahnya sendiri:
Itu tercepat yang pernah saya lihat.
Jika kita mengevaluasi exponentiation yang lebih rendah seperti
6^6
, maka perintah waktu menghasilkan hasil yang mengejutkan - menggunakanfor
perintah loop yang sama yang kita gunakan sekarang kita miliki:Jadi dengan integer yang lebih kecil
bc
tiba-tiba jauh lebih cepat ?? Dari sistem reboot untuk menjalankan kedua tidak ada bedanya. Namun pada saat yang sama, jika kita menggunakantimeit
untuk Python, kita mendapatkan:Ini adalah mikrodetik , bukan milidetik, jadi ini tidak cocok dengan hasil yang jauh lebih lambat menggunakan
for
loop. Mungkin alat lain diperlukan untuk menguji ini lebih lanjut dan seperti yang telah dijelaskan orang lain ada lebih dari memenuhi mata di sini. Tampaknya Python lebih cepat dalam skenario pertanyaan tetapi tidak jelas apakah kesimpulan dapat ditarik lebih dari itu ...1. Tak perlu dikatakan itu di luar lingkup sesuatu seperti ekspansi aritmatika gema yaitu
echo $((6**6**6))
-bash
juga kebetulan asosiatif yang tepat untuk itu yaitu6^6^6 = 6^(6^6)
.2. Bandingkan dengan ini:
6 6 ^ 6 ^ p
.3. Mungkin perintah waktu GNU memberikan lebih banyak info saat dijalankan pada BSD UNIX (dokumen info waktu GNU): Sebagian besar informasi yang ditampilkan oleh 'waktu' berasal dari panggilan sistem 'wait3'. Jumlahnya hanya sebagus yang dikembalikan oleh 'wait3'. Banyak sistem tidak mengukur semua sumber daya yang 'waktu' dapat laporkan; sumber daya tersebut dilaporkan sebagai nol. Sistem yang mengukur sebagian besar atau semua sumber daya didasarkan pada 4.2 atau 4.3BSD. Rilis BSD kemudian menggunakan kode manajemen memori yang berbeda yang mengukur lebih sedikit sumber daya. - Pada sistem yang tidak memiliki panggilan 'wait3' yang mengembalikan informasi status, panggilan sistem 'kali' digunakan sebagai gantinya. Ini memberikan informasi yang jauh lebih sedikit daripada 'wait3', jadi pada sistem 'waktu' itu melaporkan sebagian besar sumber daya sebagai nol.
sumber