Sepanjang section ini kita berulang kali menulis “speedup Nx” — angka sebesar itu hanya berarti bila cara mengukurnya jujur. Benchmark yang buruk (satu run, tanpa warm-up, data kecil) bisa membalik kesimpulan: metode yang lambat tampak cepat karena kebetulan diukur saat mesin lapang. Chapter penutup ini merangkum disiplin pengukuran menjadi pola siap pakai: verifikasi hasil dulu, panaskan kode, ukur berkali-kali, laporkan dengan konteks. Cakupan materinya:
- Prinsip benchmark adil: warm-up, banyak iterasi, statistik mediana
- Pola wajib:
asserthasil identik sebelum membandingkan waktu - Pitfall: JIT warmup, cache CPU, noise OS, data terlalu kecil
- Melaporkan hasil dengan environment dan konsep regresi timing di CI
Karena contoh membutuhkan fungsi pembanding (jumlahLoop), contoh.m ditulis sebagai function file — bentuk yang berjalan identik di MATLAB dan Octave.
Prinsip Benchmark Adil #
Empat prinsip menopang pengukuran yang bisa dipercaya. Warm-up: eksekusi pertama membayar biaya sekali jalan (kompilasi JIT, pemuatan library, cache CPU dingin) yang tidak mencerminkan steady-state. Banyak iterasi: satu run adalah sampel tunggal — noise sistem bisa 2x lebih besar dari efek yang diukur. Statistik ringkas: mediana beberapa run menolak outlier (pembaruan OS, proses lain) tanpa peduli arah; minimum berguna sebagai “batas bawah yang mampu”, tapi jangan dipakai sendirian untuk menyimpulkan. Kontrol mesin: bandingkan metode pada run yang berselang-seling di mesin yang sama — jangan membandingkan angka antar mesin atau antar jam.
| Prinsip | Alasan | Wujud dalam kode |
|---|---|---|
| Warm-up | run pertama tidak khas | eksekusi sekali tanpa dicatat |
| Banyak iterasi | satu run = sampel tunggal | for r = 1:5 |
| Mediana, bukan satu run | outlier OS & beban latar | median(waktu, 2) |
| Urutan diselang-seling | tren panas/dingin CPU | a,b,c,a,b,c — bukan a,a,a,b,b,b |
Verifikasi Sebelum Kecepatan #
Pola paling penting chapter ini: dua implementasi yang dibandingkan harus terbukti identik dulu. Benchmark atas kode yang salah hanya mengukur dua cara menghasilkan jawaban berbeda. contoh.m memakai data integer (randi) agar ketiga metode menghasilkan jumlah yang persis sama — pembulatan floating point tidak ikut bermain:
n = 200000;
rng(42); % seed tetap: total verifikasi deterministik
v = randi([1 100], 1, n); % integer: hasil ketiga metode identik persis
a1 = jumlahLoop(v);
a2 = sum(v);
a3 = v * ones(n, 1);
identik = isequal(a1, a2) && isequal(a2, a3);
assert(identik); % hasil beda = benchmark tidak sah, hentikan
fprintf('verifikasi: ketiga metode identik = %d (total %d)\n\n', identik, a1);Output yang Dihasilkan:
verifikasi: ketiga metode identik = 1 (total 10107882)Mediana dari N Run #
Setelah lolos verifikasi, ukur: panaskan ketiga metode sekali, lalu jalankan lima putaran yang menyelingi ketiganya. Tiga metode diuji: akumulator loop, sum bawaan, dan perkalian dot v * ones(n, 1):
% warm-up: eksekusi pertama membayar JIT dan cache dingin
jumlahLoop(v);
sum(v);
v * ones(n, 1);
banyakRun = 5;
waktu = zeros(3, banyakRun);
for r = 1:banyakRun
tic; jumlahLoop(v); waktu(1, r) = toc;
tic; sum(v); waktu(2, r) = toc;
tic; v * ones(n, 1); waktu(3, r) = toc;
end
mediana = median(waktu, 2);
metode = {'loop akumulator', 'sum bawaan', 'perkalian dot'};
fprintf('%-18s %10s %10s %10s\n', 'metode', 'min (s)', 'mediana', 'speedup');
terlambat = max(mediana);
for k = 1:3
fprintf('%-18s %10.5f %10.5f %9.0fx\n', ...
metode{k}, min(waktu(k, :)), mediana(k), terlambat / mediana(k));
end
fprintf('\nwaktu loop per run : %.4f %.4f %.4f %.4f %.4f\n', waktu(1, :));
fprintf('mediana 5 run : %.4f (lebih stabil dari satu run)\n', mediana(1));Output yang Dihasilkan:
metode min (s) mediana speedup
loop akumulator 0.22908 0.23727 1x
sum bawaan 0.00017 0.00020 1198x
perkalian dot 0.00030 0.00036 668x
waktu loop per run : 0.2457 0.2306 0.2291 0.2519 0.2373
mediana 5 run : 0.2373 (lebih stabil dari satu run)Mari kita bedah baris-baris kode di atas:
- Baris 2-4 (
jumlahLoop(v); sum(v); ...): warm-up — ketiga jalur kode dieksekusi sekali penuh tanpa hasil dicatat. - Baris 6-12 (
for r = 1:banyakRun): lima putaran; setiap putaran menyelingi a-b-c sehingga kondisi mesin naik-turun menimpa ketiganya secara adil, danwaktumenjadi matriks3 × 5. - Baris 14 (
mediana = median(waktu, 2);): mediana per baris (dimensi 2) — satu angka per metode yang kebal outlier. - Baris 18 (
terlambat = max(mediana);): patokan speedup adalah metode terlambat, sehingga tabel membaca “berapa kali lebih cepat dari baseline loop”. - Baris 23 (
fprintf('...%.4f %.4f...', waktu(1, :))): memperlihatkan lima waktu mentah — bukti bahwa noise itu nyata, bukan teori.
Untuk pengukuran satu fungsi di MATLAB, timeit (R2013b+) melakukan pola yang sama secara otomatis — beberapa eksekusi lalu mediana, pada function handle: t = timeit(@() sum(v)). timeit tidak tersedia di Octave; contoh.m ini adalah padanan manualnya yang portabel.
Pitfall yang Sering Menipu #
| Pitfall | Gejala | Penangkal |
|---|---|---|
| JIT warmup | run pertama 5-10x lebih lambat | buang run pertama |
| Cache CPU | data kecil muat di cache → menyesatkan | gunakan ukuran data realistis |
| OS noise | satu run melenceng jauh | mediana N run, ulangi bila perlu |
| Data terlalu kecil | selisih < noise pengukuran | pastikan beda waktu » noise |
| Compiler/CPU berbeda | kesimpulan tidak berlaku | laporkan environment |
Melaporkan dan Menjaga Regresi #
Hasil benchmark yang tidak bisa direproduksi adalah opini. Laporan minimal mencakup: versi MATLAB/Octave (version), spesifikasi CPU dan RAM, beban mesin saat mengukur, ukuran data, jumlah run, dan statistik yang dipakai (mediana 5 run). Untuk perbandingan antar waktu (mis. sebelum/sesudah refactor), sertakan environment yang sama atau nyatakan perbedaannya. Prinsip yang sama berskala menjadi CI regression timing: pipeline menjalankan benchmark standar di tiap perubahan kode dan menandai penurunan di atas ambang (misal mediana memburuk >20%) — penurunan kecil dibiarkan agar noise tidak menyalakan alarm palsu. Ambang longgar plus mediana adalah kompromi antara kepekaan dan ketenangan.
Ringkasan #
Benchmark yang jujur adalah urutan: verifikasi identitas hasil (assert dengan toleransi yang dinyatakan), warm-up, banyak run yang menyelingi metode, mediana, lalu laporan lengkap dengan environment. Pitfall klasiknya — JIT, cache, noise OS, data kecil — punya penangkal mekanis yang kita terapkan langsung pada tiga metode penjumlahan: mediana 0.2373 s untuk loop, 0.00020 s untuk sum, 0.00036 s untuk dot — dengan klaim speedup yang kini punya bukti dan batas. Dengan ini, seluruh alat section Optimasi dan Performa — dari profiler sampai laporan benchmark — sudah lengkap di tangan kita.