Saya telah menemukan itu max
lebih lambat daripada sort
fungsi di Python 2 dan 3.
Python 2
$ python -m timeit -s 'import random;a=range(10000);random.shuffle(a)' 'a.sort();a[-1]'
1000 loops, best of 3: 239 usec per loop
$ python -m timeit -s 'import random;a=range(10000);random.shuffle(a)' 'max(a)'
1000 loops, best of 3: 342 usec per loop
Python 3
$ python3 -m timeit -s 'import random;a=list(range(10000));random.shuffle(a)' 'a.sort();a[-1]'
1000 loops, best of 3: 252 usec per loop
$ python3 -m timeit -s 'import random;a=list(range(10000));random.shuffle(a)' 'max(a)'
1000 loops, best of 3: 371 usec per loop
Mengapa adalah max
( O(n)
) lebih lambat dibandingkan dengan sort
fungsi ( O(nlogn)
)?
python
sorting
max
python-internals
WeizhongTu
sumber
sumber
a.sort()
bekerja di tempat. Cobasorted(a)
sort
semacam, dan kemudiana
diurutkan selamanyaJawaban:
Anda harus sangat berhati-hati saat menggunakan
timeit
modul dengan Python.Di sini kode inisialisasi dijalankan sekali untuk menghasilkan larik acak
a
. Kemudian sisa kode dijalankan beberapa kali. Pertama kali ini mengurutkan larik, tetapi setiap kali Anda memanggil metode pengurutan pada larik yang sudah diurutkan. Hanya waktu tercepat yang dikembalikan, jadi Anda sebenarnya menghitung waktu berapa lama waktu yang dibutuhkan Python untuk mengurutkan array yang sudah diurutkan.Bagian dari algoritma pengurutan Python adalah untuk mendeteksi ketika larik sudah sebagian atau seluruhnya diurutkan. Ketika benar-benar diurutkan, ia hanya perlu memindai sekali melalui array untuk mendeteksi ini dan kemudian berhenti.
Jika sebaliknya Anda mencoba:
kemudian pengurutan terjadi pada setiap putaran waktu dan Anda dapat melihat bahwa waktu untuk mengurutkan array memang jauh lebih lama daripada hanya menemukan nilai maksimum.
Edit: @ Skyking ini jawabannya menjelaskan bagian saya meninggalkan dijelaskan:
a.sort()
tahu itu bekerja pada daftar sehingga dapat langsung mengakses elemen.max(a)
bekerja pada sembarang iterable sehingga harus menggunakan iterasi generik.sumber
a.sort()
tahu itu berfungsi pada daftar sehingga dapat langsung mengakses elemen.max(a)
bekerja pada urutan arbitrer untuk tidak menggunakan iterasi generik.listsort.txt
menjelaskan "Ini memiliki kinerja supernatural pada banyak jenis larik yang tersusun sebagian (kurang dari lg (N!) Diperlukan perbandingan, dan sesedikit N-1)" dan kemudian menjelaskan semua jenis pengoptimalan berdarah. Saya kira ini bisa membuat banyak asumsi yangmax
tidak bisa, yaitu pengurutan tidak lebih cepat secara asimtotik.Pertama, perhatikan yang
max()
menggunakan protokol iterator , sementaralist.sort()
menggunakan kode ad-hoc . Jelas, menggunakan iterator adalah overhead yang penting, itulah mengapa Anda mengamati perbedaan waktu itu.Namun, selain itu, pengujian Anda tidak adil. Anda menjalankan
a.sort()
daftar yang sama lebih dari sekali. The algoritma yang digunakan oleh Python secara khusus dirancang untuk menjadi cepat untuk sudah (sebagian) diurutkan data. Pengujian Anda menunjukkan bahwa algoritme tersebut melakukan tugasnya dengan baik.Ini adalah tes yang adil:
Di sini saya membuat salinan daftar setiap saat. Seperti yang Anda lihat, urutan besarnya hasil berbeda: mikro vs milidetik, seperti yang kita perkirakan.
Dan ingat: big-Oh menentukan batas atas! Batas bawah untuk algoritma pengurutan Python adalah Ω ( n ). Menjadi O ( n log n ) tidak secara otomatis menyiratkan bahwa setiap proses membutuhkan waktu yang sebanding dengan n log n . Ini bahkan tidak menyiratkan bahwa itu harus lebih lambat dari algoritma O ( n ), tapi itu cerita lain. Yang penting untuk dipahami adalah bahwa dalam beberapa kasus yang menguntungkan, algoritme O ( n log n ) dapat berjalan dalam waktu O ( n ) atau kurang.
sumber
Ini bisa jadi karena
l.sort
adalah anggotalist
whilemax
adalah fungsi generik. Ini berarti bahwal.sort
dapat mengandalkan representasi internallist
sementaramax
harus melalui protokol iterator generik.Ini membuat setiap pengambilan elemen
l.sort
lebih cepat daripada setiap elemen yang diambilmax
.Saya berasumsi bahwa jika Anda malah menggunakan
sorted(a)
Anda akan mendapatkan hasil lebih lambat darimax(a)
.sumber
sorted(a)
lebih lambat darimax(a)
. Tidak mengherankan Kecepatannya hampir sama dengana.sort()
, tetapi dugaan Anda tentang alasan mengapa tidak — itu karena OP membuat kesalahan dalam pengujian mereka seperti yang ditunjukkan dalam jawaban yang diterima.log(n)
faktor kerumitan. Artinya suatuO(n)
algoritma hanya dijamin akan lebih cepat daripadaO(nlogn)
algoritma yang cukup besarn
(misalnya karena waktu untuk setiap operasi mungkin berbeda antar algoritma -nlogn
langkah cepat mungkin lebih cepat daripadan
langkah lambat). Persis di mana titik impas tidak dipertimbangkan dalam kasus ini (tetapi orang harus menyadari bahwalog n
faktor tersebut bukanlah faktor yang sangat besar untuk bertubuh keciln
).