Itu bukan steno.
The +=
simbol muncul dalam bahasa C pada 1970-an, dan - dengan C gagasan "assembler pintar" sesuai dengan mode instruksi mesin dan adressing jelas berbeda:
Hal-hal seperti " i=i+1
", "i+=1
"dan" ++i
", meskipun pada level abstrak menghasilkan efek yang sama, berhubungan pada level rendah dengan cara kerja prosesor yang berbeda.
Secara khusus ketiga ekspresi tersebut, dengan asumsi i
variabel berada di alamat memori yang disimpan dalam register CPU (sebut saja D
- anggap sebagai "penunjuk ke int") dan ALU prosesor mengambil parameter dan mengembalikan hasil dalam "Akumulator" (sebut saja A - pikirkan sebagai int).
Dengan kendala-kendala ini (sangat umum di semua mikroprosesor dari periode itu), kemungkinan besar terjemahannya
;i = i+1;
MOV A,(D); //Move in A the content of the memory whose address is in D
ADD A, 1; //The addition of an inlined constant
MOV (D) A; //Move the result back to i (this is the '=' of the expression)
;i+=1;
ADD (D),1; //Add an inlined constant to a memory address stored value
;++i;
INC (D); //Just "tick" a memory located counter
Cara pertama untuk melakukannya adalah disoptimal, tetapi lebih umum ketika beroperasi dengan variabel daripada konstan ( ADD A, B
atau ADD A, (D+x)
) atau ketika menerjemahkan ekspresi yang lebih kompleks (mereka semua mendidih dalam mendorong operasi prioritas rendah dalam tumpukan, sebut prioritas tinggi, pop dan ulangi sampai semua argumen dihilangkan).
Yang kedua lebih khas dari "mesin negara": kita tidak lagi "mengevaluasi ekspresi", tetapi "mengoperasikan nilai": kita masih menggunakan ALU, tetapi menghindari memindahkan nilai sekitar karena hasilnya diperbolehkan untuk mengganti parameter. Instruksi semacam ini tidak dapat digunakan di mana ekspresi yang lebih rumit diperlukan: i = 3*i + i-2
tidak dapat dioperasikan di tempat, karena i
diperlukan lebih banyak kali.
Yang ketiga sederhana bahkan tidak mempertimbangkan gagasan "penambahan", tetapi menggunakan sirkuit yang lebih "primitif" (dalam arti komputasi) untuk penghitung. Instruksi ini disingkat, memuat lebih cepat dan dieksekusi segera, karena jaringan kombinatorial diperlukan untuk retrofit register untuk menjadikannya penghitung yang lebih kecil, dan karenanya lebih cepat daripada yang dari penambah penuh.
Dengan kompiler kontemporer (lihat C, sekarang), memungkinkan optimisasi kompiler, korespondensi dapat ditukar berdasarkan kenyamanan, tetapi masih ada perbedaan konseptual dalam semantik.
x += 5
cara
- Temukan tempat yang diidentifikasi oleh x
- Tambahkan 5 ke dalamnya
Tetapi x = x + 5
berarti:
- Evaluasi x + 5
- Temukan tempat yang diidentifikasi oleh x
- Salin x ke akumulator
- Tambahkan 5 ke akumulator
- Simpan hasilnya dalam x
- Temukan tempat yang diidentifikasi oleh x
- Salin akumulator ke sana
Tentu saja, optimasi bisa
- jika "menemukan x" tidak memiliki efek samping, dua "penemuan" dapat dilakukan sekali (dan x menjadi alamat yang disimpan dalam register pointer)
- dua salinan tersebut dapat dihilangkan jika ADD diterapkan
&x
sebagai ganti ke akumulator
sehingga membuat kode yang dioptimalkan bertepatan x += 5
satu.
Tetapi ini dapat dilakukan hanya jika "menemukan x" tidak memiliki efek samping, sebaliknya
*(x()) = *(x()) + 5;
dan
*(x()) += 5;
secara semantik berbeda, karena x()
efek samping (mengakui x()
adalah fungsi melakukan hal-hal aneh di sekitar dan mengembalikan int*
) akan diproduksi dua kali atau sekali.
Kesetaraan antara x = x + y
dan x += y
karenanya karena kasus khusus di mana +=
dan =
diterapkan pada nilai-l langsung.
Untuk pindah ke Python, itu mewarisi sintaksis dari C, tetapi karena tidak ada terjemahan / optimasi SEBELUM eksekusi dalam bahasa yang ditafsirkan, hal-hal tidak harus begitu terkait erat (karena ada satu langkah penguraian yang kurang). Namun, seorang juru bahasa dapat merujuk ke rutinitas eksekusi yang berbeda untuk tiga jenis ekspresi, mengambil keuntungan dari kode mesin yang berbeda tergantung pada bagaimana ekspresi dibentuk dan pada konteks evaluasi.
Bagi yang suka lebih detail ...
Setiap CPU memiliki ALU (unit aritmatika-logis) yaitu, pada intinya, jaringan kombinatorial yang input dan outputnya "dicolokkan" ke register dan / atau memori tergantung pada opcode instruksi.
Operasi biner biasanya diimplementasikan sebagai "pengubah register akumulator dengan input yang diambil" di suatu tempat ", di mana suatu tempat dapat berada - di dalam aliran instruksi itu sendiri (khas untuk manifes kontan: ADD A 5) - di dalam registri lain (tipikal untuk ekspresi ekspresi dengan temporaries: eg ADD AB) - di dalam memori, pada alamat yang diberikan oleh register (tipikal pengambilan data misalnya: ADD A (H)) - H, dalam hal ini, berfungsi seperti penunjuk dereferencing.
Dengan kodesemu ini, x += 5
adalah
ADD (X) 5
sementara x = x+5
ini
MOVE A (X)
ADD A 5
MOVE (X) A
Artinya, x + 5 memberikan sementara yang kemudian ditugaskan. x += 5
beroperasi langsung pada x.
Implementasi aktual tergantung pada set instruksi nyata dari prosesor: Jika tidak ada ADD (.) c
opcode, kode pertama menjadi yang kedua: tidak mungkin.
Jika ada opcode seperti itu, dan optimisasi diaktifkan, ekspresi kedua, setelah menghilangkan gerakan mundur dan menyesuaikan opcode register, menjadi yang pertama.
x += 5
dari CLRx = x + 5
? Atau itu benar-benar hanya gula sintaksis seperti yang Anda sarankan?