Dua catatan baseline dan dua catatan vectorized kini tersedia. Menganalisis hasil benchmark berarti tiga pekerjaan: merapikan angka menjadi tabel, menjelaskan pola di baliknya, dan menetapkan batas keabsahan kesimpulan. Kita kerjakan berurutan, ditutup laporan dan pemeriksaan akhir.

Membaca Tabel Hasil #

Tabel berikut merangkum contoh hasil pengukuran pada mesin penulis (2 CPU, 4 GB RAM, NumPy 2.1.3). Angka waktunya contoh — angka waktu bervariasi antar komputer — yang stabil adalah polanya:

SkenarioLoop Python (contoh)Vectorized (contoh)Rasio (contoh)
Jumlah elemen~83 ms~0.46 ms~180x
Dot product~221 ms~0.33 ms~670x
Boolean filtering~110 ms~6.0 ms~18x

Tiga interpretasi menjelaskan polanya:

  1. Loop Python membayar biaya tetap per elemen. Setiap iterasi mengeksekusi bytecode, membaca satu scalar dari array, dan membuat objek float baru. Satu juta elemen berarti satu juta kali biaya itu — inilah dasar rasio ratusan kali pada reduksi.
  2. np.dot memegang rasio terbesar. Di balik satu panggilan itu ada rutinitas BLAS dengan instruksi SIMD dan penggunaan cache yang rapi (bab Dot Product), sementara np.sum tetap secepat satu loop C murni.
  3. Boolean filtering menang paling tipis. Operasinya tidak hanya membaca: data[data > ambang] harus mengalokasikan dan mengisi array baru berukuran sekitar 4 MB. Karena pekerjaannya mendekati memory-bound, rasionya turun ke belasan-puluhan kali — tetap berarti, jauh dari ratusan.

Kapan Rasio Percepatan Mengecil #

Rasio besar bukan hukum alam. Angka itu menyusut pada kondisi-kondisi berikut:

  1. Array kecil: biaya tetap satu pemanggilan NumPy (pembuatan objek, pemeriksaan bentuk) mendominasi; pada ratusan elemen, loop pun bisa kompetitif — bab Kapan NumPy Bukan Pilihan Terbaik membedah batas ini.
  2. Operasi memory-bound: kecepatan dibatasi transfer RAM, bukan logika komputasi; mengecilkan dtype (bab Memilih dtype yang Efisien) sering lebih berdampak daripada mengubah implementasi.
  3. Konversi dtype di tengah jalan: data yang harus dikonversi sebelum operasi NumPy menambah biaya salin yang ikut terukur.
  4. Operasi yang sudah vectorized: memanggil np.sum di dalam loop Python justru menggabungkan dua biaya; rasio kembali besar hanya bila loopnya dihilangkan, bukan diberi isi yang lebih cepat.

Yang tidak berubah oleh ukuran adalah kebenaran hasil. Pemeriksaan kesetaraan pada tiga skala berikut menegaskan bahwa loop dan vectorized selalu sepakat:

python
import numpy as np

def jumlah_loop(data):
    total = 0.0
    for nilai in data:
        total += nilai
    return total

rng = np.random.default_rng(42)
for n in [1_000, 100_000, 1_000_000]:
    data = rng.random(n)
    sama = np.isclose(jumlah_loop(data), np.sum(data))
    print(f"n={n:>9,}: hasil sama -> {sama}")

Output yang Dihasilkan:

text
n=    1,000: hasil sama -> True
n=  100,000: hasil sama -> True
n=1,000,000: hasil sama -> True

Penjelasannya:

  1. Baris 8 (for n in [1_000, 100_000, 1_000_000]): tiga ukuran diuji berurutan; karena satu generator dipakai bergantian, datanya tetap deterministik meski berbeda antar ukuran.
  2. Baris 10-11 (np.isclose(...)): kesetaraan penjumlahan diuji dengan toleransi; True di ketiga skala berarti pilihan ukuran tidak mengubah kebenaran, hanya durasinya.

Checklist Benchmark yang Adil #

Sebelum memakai angka benchmark — milik sendiri maupun milik orang lain — periksa daftar ini:

  1. Tulis dulu pemeriksaan kebenaran (array_equal / isclose), baru alat ukurnya.
  2. Pakai data yang identik untuk kedua kubu: seed sama, dtype sama, ukuran sama.
  3. Gunakan timeit.repeat dengan number yang disesuaikan durasi; jangan puas dengan sekali ukur.
  4. Laporkan nilai terkecil atau median, bukan rata-rata mentah yang mudah terseret gangguan.
  5. Warm-up dulu: jalankan sekali tanpa dicatat sebelum serangkaian pengukuran.
  6. Catat lingkungan: CPU, RAM, versi Python, dan versi NumPy.
  7. Jaga kondisi sama selama pengukuran — urutan kubu, suhu mesin, dan proses latar.

Laporan Proyek #

Seluruh hasil proyek dirangkum dalam satu tabel. Baris deterministik bisa diverifikasi ulang kapan saja; baris ilustratif hanya contoh dari satu mesin:

BesaranNilaiSifat
Input per array1.000.000 elemen float64 (8 MB)deterministik
Kebenaran jumlah & dotnp.isclose Truedeterministik
Kebenaran filternp.array_equal True (499.793 elemen)deterministik
Memori hasil filter3.998.344 byte (sekitar 4 MB)deterministik
Rasio jumlah~150-180xilustratif
Rasio dot~650-700xilustratif
Rasio filter~18-23xilustratif

Kesimpulan satu kalimat: untuk array besar, vectorization memberi percepatan puluhan hingga ratusan kali dengan hasil yang setara — dan setiap klaim kebenarannya tertaut ke pemeriksaan yang dapat dijalankan ulang. Bila proyek dikembangkan, struktur berkasnya natural: src/skenario.py menyimpan data dan enam fungsi kompetitor, sedangkan src/benchmark.py menjalankan timeit.repeat lalu menyusun tabel di atas.

Pemeriksaan Akhir #

Script terakhir merangkum seluruh klaim kebenaran proyek ke dalam satu blok yang berdiri sendiri:

python
import numpy as np

rng = np.random.default_rng(42)
data = rng.random(1_000_000)
bobot = rng.random(1_000_000)

def jumlah_loop(data):
    total = 0.0
    for nilai in data:
        total += nilai
    return total

def jumlah_vectorized(data):
    return np.sum(data)

def dot_loop(a, b):
    total = 0.0
    for i in range(len(a)):
        total += a[i] * b[i]
    return total

def dot_vectorized(a, b):
    return np.dot(a, b)

def filter_loop(data, ambang):
    hasil = []
    for nilai in data:
        if nilai > ambang:
            hasil.append(nilai)
    return np.array(hasil)

def filter_vectorized(data, ambang):
    return data[data > ambang]

assert np.isclose(jumlah_loop(data), jumlah_vectorized(data))
assert np.isclose(dot_loop(data, bobot), dot_vectorized(data, bobot))
assert np.array_equal(filter_loop(data, 0.5), filter_vectorized(data, 0.5))
print("Semua pemeriksaan lulus")

Output yang Dihasilkan:

text
Semua pemeriksaan lulus

Cara kerjanya:

  1. Enam fungsi kompetitor didefinisikan ulang dalam satu blok agar script berdiri sendiri dan bisa disalin keluar dari halaman ini.
  2. Tiga assertion memeriksa ketiga skenario: np.isclose untuk penjumlahan dan dot product (beda urutan penjumlahan), np.array_equal untuk filter (identik bit-per-bit). Kegagalan mana pun menghentikan script dengan AssertionError, sehingga baris print hanya tercapai bila semuanya lulus.

Dengan itu, proyek benchmark selesai: klaim performa kini punya rancangan pengukuran, contoh angka yang jujur, interpretasi yang bisa dipertanggungjawabkan, dan pemeriksaan kebenaran yang menetap.