Bab sebelumnya membuktikan bahwa loop dan vectorization menghasilkan nilai yang sama. Pertanyaan yang tersisa: seberapa besar selisih waktunya, dan dari mana selisih itu berasal? Kita jawab dengan pengukuran nyata memakai time.perf_counter — fungsi timer Python beresolusi tinggi yang tepat untuk menyapu potongan waktu berorde milidetik.
Prinsip pengukurannya konservatif: pastikan dulu kedua pendekatan menghasilkan array yang identik, ukur keduanya pada tugas yang sama, lalu nyatakan kesimpulan secara kualitatif. Angka waktu memang berbeda di tiap komputer, tetapi polanya selalu sama arah.
Membuktikan hasil yang sama #
Uji tugasnya: menghitung y = 2x + 1 untuk seratus ribu elemen, sekali dengan loop yang mengisi array kosong, sekali dengan ekspresi array utuh:
import numpy as np
n = 100_000
a = np.arange(1, n + 1, dtype=np.float64)
hasil_loop = np.empty(n)
for i in range(n):
hasil_loop[i] = a[i] * 2 + 1
hasil_vektor = a * 2 + 1
print("bentuk loop :", hasil_loop.shape)
print("bentuk vektor:", hasil_vektor.shape)
print("hasil sama :", np.array_equal(hasil_loop, hasil_vektor))Output yang Dihasilkan:
bentuk loop : (100000,)
bentuk vektor: (100000,)
hasil sama : True- Baris 4-5 (
a): arrayfloat64berisi 1 sampai 100000 sebagai bahan uji. - Baris 7-9 (loop):
np.empty(n)menyiapkan wadah hasil, lalu loop mengisi tiap posisi dengana[i] * 2 + 1. - Baris 11 (
hasil_vektor): ekspresi yang sama ditulis untuk array utuh tanpa indeks. - Baris 13-15: kedua hasil berbentuk
(100000,)dannp.array_equalmenyatakanTrue— fondasi sebelum membandingkan waktu.
Mengukur waktu kedua pendekatan #
Blok berikut mengukur durasi tiap pendekatan dengan time.perf_counter:
# notest
import time
import numpy as np
n = 100_000
a = np.arange(1, n + 1, dtype=np.float64)
mulai = time.perf_counter()
hasil_loop = np.empty(n)
for i in range(n):
hasil_loop[i] = a[i] * 2 + 1
waktu_loop = time.perf_counter() - mulai
mulai = time.perf_counter()
hasil_vektor = a * 2 + 1
waktu_vektor = time.perf_counter() - mulai
print("hasil sama :", np.array_equal(hasil_loop, hasil_vektor))
print("waktu loop python :", waktu_loop)
print("waktu vectorized :", waktu_vektor)
print("kesimpulan : vectorization jauh lebih cepat")Output yang Dihasilkan:
hasil sama : True
waktu loop python : 0.02278449500045099
waktu vectorized : 0.0003594470008465578
kesimpulan : vectorization jauh lebih cepatAngka waktu berbeda di tiap komputer — dua angka di atas hanyalah contoh dari satu kali eksekusi. Yang layak dibaca adalah selisih orde: loop Python memakan puluhan milidetik, sedangkan ekspresi ter-vektorisasi selesai dalam sepersekian milidetik, meskipun keduanya mengerjakan seratus ribu elemen.
- Baris 9-13 (pengukuran loop):
perf_counterdipanggil sebelum dan sesudah pekerjaan; selisihnya adalah durasi pekerjaan dalam detik. - Baris 15-17 (pengukuran vectorized): pola yang sama diterapkan pada ekspresi array utuh.
- Baris 19-22 (kesimpulan): baris pertama menegaskan kembali persamaan hasil; dua baris berikutnya melaporkan durasi; baris terakhir menyatakan kesimpulan kualitatif tanpa bergantung pada angka tertentu.
Menjumlahkan dengan akurasi identik #
Vectorization bukan soal kebenaran — loop juga menghitung dengan benar. Pada penjumlahan bilangan bulat, hasil keduanya dapat dibandingkan secara persis:
import numpy as np
b = np.arange(1, 1001)
total_loop = 0
for x in b:
total_loop = total_loop + x
print("total loop :", total_loop)
print("total vektor :", b.sum())
print("sama :", total_loop == b.sum())Output yang Dihasilkan:
total loop : 500500
total vektor : 500500
sama : True- Baris 5-7 (loop): akumulator Python menjumlahkan 1000 elemen satu per satu, menghasilkan
500500. - Baris 9 (
b.sum()): method NumPy meratakan seluruh array dalam satu panggilan dan menghasilkan nilai yang sama persis untuk bilangan bulat.
Dari mana selisih kecepatan berasal #
Selisih orde tersebut lahir dari letak iterasi, bukan dari algoritma yang berbeda:
- Loop Python: interpreter mengeksekusi bytecode untuk setiap elemen — membaca
a[i], membuat objek hasil sementara, memeriksa tipe, lalu menuliskannya kembali. Biaya itu terbayar seratus ribu kali. - Vectorized: satu panggilan fungsi C; loop berjalan di dalam kode C dengan tipe data tetap, tanpa membuat objek Python per elemen, tanpa penafsiran ulang.
- Alokasi memori: hasil ekspresi ter-vektorisasi dialokasikan sekali sebagai satu buffer, bukan ditulis elemen demi elemen lewat antarmuka Python.
| Sumber biaya | Loop Python | Vectorized |
|---|---|---|
| Eksekusi instruksi | per elemen, oleh interpreter | per array, oleh kode C |
| Objek Python baru | satu per elemen | satu per array hasil |
| Pemeriksaan tipe | per elemen | sekali per operasi |