⚡ Jawaban Singkat / Key Takeaways
Python 3.13 akhirnya punya JIT compiler bawaan, tapi bukan JIT ala V8 atau HotSpot. Teknik yang dipakai namanya copy-and-patch: CPython menyalin template assembly (stencil) yang udah disiapin sebelumnya, lalu “nambal” (patch) bagian yang perlu disesuaikan kayak immediate values dan alamat memori. Hasilnya: kompilasi super cepat, overhead rendah, tapi optimasi terbatas. Jangan harap speedup 10x kayak PyPy. Ini baru langkah pertama.
JIT di Python 3.13 Itu Tiba-tiba Ada, dan Banyak yang Salah Paham
Kamu mungkin udah denger kabar: Python 3.13 rilis Oktober 2024 dengan JIT compiler. Reaksi komunitas langsung heboh. Sebagian bilang “akhirnya Python secepat C++!”, sebagian lagi skeptis “paling cuma gimmick.” Dua-duanya salah.
JIT di CPython bukan proyek dadakan. Brandt Bucher, core developer CPython, udah mengerjakannya sejak 2023 lewat PEP 744. Tapi yang lebih menarik bukan soal “kapan” atau “siapa”, melainkan gimana caranya. Karena teknik yang dipilih bukan tracing JIT kayak PyPy, bukan method JIT kayak HotSpot JVM, tapi sesuatu yang relatif jarang dipakai di production language runtime: copy-and-patch compilation.

Apa Itu Copy-and-Patch? Analogi Stensil yang Bikin Ngerti Dalam 2 Menit
Bayangin kamu lagi bikin poster buat konser. Kamu nggak gambar huruf satu-satu dari nol. Kamu ambil stensil (template), tempel, lalu semprot cat. Stensil menyediakan kerangka; kamu tinggal isi detailnya.
Copy-and-patch bekerja dengan cara yang sama. CPython nggak menghasilkan machine code dari nol setiap kali nemu bytecode. Sebaliknya, compiler punya koleksi stencil, yaitu potongan kecil assembly x86-64 (atau AArch64) yang udah dikompilasi sebelumnya. Satu stencil untuk LOAD_FAST, satu untuk BINARY_ADD, satu untuk CALL, dan seterusnya.
Saat JIT diaktifkan, CPython:
- Copy: menyalin stencil yang sesuai ke buffer executable memory
- Patch: menambal bagian yang berubah, seperti immediate operand (konstanta numerik) dan relative offset untuk branching
Proses ini jauh lebih ringan dibanding JIT tradisional yang harus membangun intermediate representation, menjalankan optimization passes, lalu register allocation. Copy-and-patch skip semua itu.
Dari Bytecode ke Machine Code: Alur Lengkapnya
Mari kita bedah step by step. Anggap CPython nemu bytecode LOAD_FAST 0 (load variabel lokal slot 0). Tanpa JIT, interpreter bakal baca opcode, lookup di big switch-case, lalu eksekusi logic yang sesuai. Dengan JIT copy-and-patch:
Step 1: Interpreter Profiling (Tier 0)
Sebelum kompilasi terjadi, kode jalan dulu di interpreter biasa. Tapi interpreter ini punya mode khusus: instrumented bytecode. Setiap opcode punya counter kecil buat ngukur seberapa sering dieksekusi. Fungsi yang dipanggil berkali-kali (hot) akan ditandai buat naik ke tier berikutnya.

Step 2: Stencil Selection
Setelah fungsi ditandai “hot”, CPython memilih stencil yang cocok untuk setiap opcode di fungsi tersebut. Stencil ini sebenarnya adalah binary blob kecil (sekitar 20-80 bytes per opcode) yang berisi native x86-64 instruksi. Stencil dibuat saat CPython dikompilasi, bukan saat runtime.
Step 3: Copy ke Executable Buffer
Stencil yang udah dipilih disalin ke buffer memori yang dialokasikan dengan mmap dan permission PROT_READ | PROT_WRITE | PROT_EXEC. Di titik ini, kodenya masih “mentah” karena masih ada placeholder yang perlu diisi.
Step 4: Patch Immediate Values
Bayangin stencil untuk LOAD_CONST. Stencil-nya berisi instruksi assembly kayak mov rax, 0xDEADBEEF. Nilai 0xDEADBEEF adalah placeholder. Waktu patching, CPython ganti placeholder itu dengan alamat aktual objek PyObject* dari konstanta yang mau di-load.
Proses ini cepat banget karena cuma modifikasi beberapa byte di posisi yang udah diketahui. Nggak ada register allocation, nggak ada instruction selection ulang, nggak ada optimization pass.

Step 5: Eksekusi
Setelah semua placeholder dipatch, CPython tinggal lompat (jump) ke buffer executable itu. Kode jalan native, tanpa interpreter loop, tanpa opcode dispatch overhead.
Kenapa Nggak Pakai JIT Kayak PyPy atau V8?
Pertanyaan ini wajar banget. Kenapa tim CPython milih teknik yang relatif obscure ini dibanding method JIT yang udah terbukti?
Alasan utamanya: maintenance burden. CPython adalah proyek open-source yang dikelola sebagian besar oleh relawan. JIT tradisional butuh codebase yang kompleks, optimization pipeline yang panjang, dan expert di compiler backend. Kalau core developer yang bisa maintain JIT kompleks cuma 2-3 orang, begitu mereka burnout, fitur itu jadi technical debt raksasa.
Copy-and-patch punya karakteristik yang pas buat CPython:
- Kompilasi super cepat: cuma mikrodetik, bukan milidetik. Cocok buat workload Python yang banyak fungsi pendek
- Codebase kecil: implementasi awal cuma beberapa ribu baris C
- Mudah di-debug: karena transformasi dari bytecode ke machine code sifatnya 1:1, nggak ada IR yang menghilangkan informasi source-level
- Portabel: stencil dibuat per arsitektur (x86-64, AArch64), tapi logic copy-patch-nya sendiri platform-agnostic

Batasannya: Apa yang Nggak Dilakukan JIT Ini
Ini bagian penting yang jarang dibahas di artikel populer. Copy-and-patch JIT CPython 3.13 nggak melakukan optimasi lintas opcode. Maksudnya, setiap opcode dikompilasi secara terisolasi. LOAD_FAST diikuti BINARY_ADD tidak akan di-fuse jadi satu instruksi LEA. Data tetap mengalir lewat stack (bukan register allocation lintas instruksi).
Beberapa limitasi spesifik yang perlu kamu tahu:
- Tidak ada inlining: fungsi kecil yang sering dipanggil tetap jadi CALL, bukan digabung ke caller
- Tidak ada escape analysis: alokasi objek tetap lewat heap, meskipun sebenernya bisa di-stack
- Tidak ada loop unrolling: loop tetap satu per satu iterasi
- Tidak ada dead code elimination: instruksi yang nggak berguna tetap dikompilasi kalau ada di bytecode
Speedup yang bisa kamu harapkan: 5-15% untuk kode CPU-bound umum. Bukan 2x, bukan 10x. Tapi ingat: ini baru fondasi. Tim CPython udah merancang arsitektur multi-tier yang memungkinkan optimasi lebih agresif di tier berikutnya.
Arsitektur Multi-Tier: Ini Baru Tier 1
Yang bikin desain ini menarik adalah visi jangka panjangnya. Brandt Bucher dan tim mendesain JIT dengan arsitektur bertingkat:
- Tier 0: Interpreter biasa dengan profiling (sebelum 3.13, ini udah ada)
- Tier 1: Copy-and-patch JIT (rilis di 3.13, opsional, off by default)
- Tier 2: Optimizing JIT (masih dalam pengembangan, belum ada timeline pasti)
Yang cerdas dari pendekatan ini: Tier 2 nantinya bisa menggunakan informasi profiling dari Tier 0 dan machine code dari Tier 1 sebagai basis buat optimasi lebih lanjut. Jadi investasi di infrastruktur copy-and-patch sekarang bukan dead end, tapi batu loncatan.
Cara Mengaktifkan dan Eksperimen Sendiri
JIT di Python 3.13 tidak aktif secara default. Kamu harus enable lewat environment variable:
export PYTHON_JIT=1
python -c "import sys; print(sys._jit_enabled)"
Atau kalau kamu build CPython dari source, tambahkan flag:
./configure --enable-experimental-jit
make
Catatan penting: JIT saat ini cuma tersedia di arsitektur x86-64 Linux/macOS dan AArch64 (ARM64). Windows support masih experimental. Kalau arsitektur kamu nggak punya stencil, JIT akan silent fallback ke interpreter biasa.
Kapan JIT Ini Worth It Buat Production Kamu?
Buat workload yang I/O-bound (network call, database query, file read), JIT nggak bakal kasih perbedaan signifikan. Overhead utamanya bukan di CPU.
JIT mulai terasa manfaatnya di:
- Data processing: NumPy/Pandas dengan loop Python murni (bukan vectorized)
- Template rendering: Jinja2, Django template dengan banyak logika
- Hashing dan serialization: JSON encode/decode dalam jumlah besar
- Game logic: update loop dengan banyak perhitungan
Untuk workload yang udah di-offload ke C extension (NumPy array operations, ML inference via PyTorch), dampak JIT bakal minimal karena bottleneck-nya bukan di interpreter.
Baca juga: Python Mulai Punya Sabuk Pengaman ala TypeScript dan Jangan Pilih Bahasa Coding Sebelum Lihat Matrix Ini.
FAQ: Python 3.13 JIT Copy-and-Patch
Apa beda copy-and-patch JIT sama PyPy?
PyPy pakai tracing JIT yang merekam hot path, lalu melakukan optimasi agresif seperti loop unrolling, allocation removal, dan type specialization. Copy-and-patch CPython jauh lebih sederhana: cuma konversi bytecode ke machine code 1:1 tanpa optimasi antar opcode. Hasilnya, PyPy bisa 5-10x lebih cepat untuk kode murni Python, tapi kompilasinya lebih lambat dan konsumsi memori lebih tinggi.
Apakah JIT 3.13 bikin Python lebih cepat dari Node.js atau Go?
Tidak. Bahkan dengan JIT aktif, Python 3.13 masih jauh lebih lambat dari V8 (JavaScript) atau Go runtime untuk workload CPU-bound. Python di-desain untuk produktivitas developer, bukan raw speed. Kalau target kamu throughput maksimal, pertimbangkan Rust atau Go, bukan upgrade Python version.
Kenapa JIT dimatiin secara default?
Karena JIT masih dalam tahap experimental. Tim CPython ingin memastikan stabilitas di berbagai workload sebelum mengaktifkannya untuk semua orang. Selain itu, JIT menambah overhead kompilasi dan konsumsi memori. Untuk script pendek yang cuma jalan sekali, JIT justru bikin lebih lambat karena ada cost kompilasi awal. Aktifkan hanya kalau kamu punya workload long-running yang CPU-bound.
Apakah semua kode Python otomatis jadi lebih cepat?
Tidak. Hanya fungsi yang dipanggil cukup sering (melewati threshold profiling) yang akan dikompilasi ke machine code. Fungsi yang cuma dipanggil sekali atau dua kali tetap jalan di interpreter biasa. Selain itu, kode yang banyak memanggil C extension (NumPy, TensorFlow, lxml) tidak banyak terpengaruh karena bottleneck-nya di dalam compiled code, bukan di interpreter Python.
Kesimpulan
Python 3.13 JIT bukan silver bullet, dan tim CPython nggak pernah mengklaim begitu. Tapi ini adalah langkah strategis yang membuka jalan buat optimasi lebih lanjut. Yang bikin menarik: pendekatan copy-and-patch dipilih bukan karena teknologinya paling keren, tapi karena paling sustainable buat proyek open-source dengan sumber daya terbatas.
Kalau kamu penasaran, coba aja sendiri. Aktifkan JIT di environment development kamu, jalankan test suite, ukur bedanya. 5-15% mungkin nggak kedengaran bombastis, tapi di production server yang ngabisin ribuan CPU-jam per bulan, itu artinya penghematan yang signifikan.
Referensi: PEP 744 — JIT Compilation, Python 3.13 What's New, Copy-and-Patch Compilation (Haoran Xu et al.).



