Bu steno değil.
+=
: Açıkça farklı makine talimat ve adresleme moduna uygun "akıllı assembler" C fikri ile - sembol 1970'lerde C dilinde göründü ve
" i=i+1
", "i+=1
"Ve" ++i
" gibi şeyler , soyut düzeyde aynı etkiyi yaratsa da, düşük seviyede işlemcinin farklı çalışma şekillerine karşılık gelir.
Özellikle bu üç ifadeler, varsayarak i
değişken bir işlemci kayıt içine depolanmış olan bellek adresi bulunur (en bunun adı izin D
ve - "int pointer" olarak düşünmek) ALU işlemcinin bir parametre alır ve bir de bir sonuca dönmek "akümülatör" (hadi A diyelim - bunu bir int olarak düşünün).
Bu kısıtlamalarla (bu dönemin tüm mikroişlemcilerinde çok yaygın), çeviri büyük olasılıkla olacaktır.
;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
Bunu yapmanın ilk yolu disoptimaldir, ancak sabit ( ADD A, B
veya ADD A, (D+x)
) yerine değişkenlerle çalışırken veya daha karmaşık ifadeler çevrildiğinde (hepsi bir yığında düşük öncelikli işlem sırasında aşağı kayıyorlarsa, yüksek öncelikli çağrı yapın, ve tüm argümanlar ortadan kalkana kadar tekrarlayın).
İkincisi “durum makinesi” için daha tipiktir: artık bir ifadeyi “değerlendirmiyoruz”, ancak “bir değeri işletiyoruz”: yine de ALU kullanıyoruz, ancak sonucun parametrenin yerine geçmesine izin verilmesini engelliyoruz. Bu tür talimatlar, daha karmaşık ifadelerin gerekli olduğu yerlerde kullanılamaz: i = 3*i + i-2
yerinde çalıştırılamaz, çünkü i
daha çok kez gereklidir.
Üçüncü-on basit, "toplama" fikrini bile düşünmez, fakat bir sayaç için daha "ilkel" (hesaplamalı anlamda) bir devre kullanır. Yönerge kısaltılır, daha hızlı yüklenir ve derhal yürütülür, çünkü bir tezgahın daha küçük olması için bir kaydın güçlendirilmesi için gerekli olan kombinatoryal ağ tam bir toplayıcıdan daha hızlıdır ve bu nedenle tam bir toplayıcıdan daha hızlıdır.
Çağdaş derleyicilerde (şimdiye kadar C'ye bakın), derleyici optimizasyonunu mümkün kılan yazışmalar, uygunluğa dayalı olarak değiştirilebilir, ancak anlambilimde hala kavramsal bir fark vardır.
x += 5
anlamına geliyor
- X ile tanımlanan yeri bulun
- Buna 5 ekle
Ancak şu x = x + 5
anlama gelir:
- Değerlendirin x + 5
- X ile tanımlanan yeri bulun
- X'i bir akümülatöre kopyala
- Aküye 5 ekleyin
- Sonucu x olarak sakla
- X ile tanımlanan yeri bulun
- Akümülatörü buna kopyalayın
Tabii ki, optimizasyon olabilir
- "x bulma" nın hiçbir yan etkisi yoksa, iki "bulma" bir kez yapılabilir (ve x bir işaretçi kaydında saklanan bir adres olur)
&x
akü yerine ADD uygulanırsa iki kopya seçilebilir
Böylece optimize edilmiş kod bir birine çakışıyor x += 5
.
Ancak bu sadece "x bulma" nın yan etkisi yoksa yapılabilir.
*(x()) = *(x()) + 5;
ve
*(x()) += 5;
anlamsal olarak farklıdır, çünkü x()
yan etkiler (kabul etmek x()
garip şeyler yapan ve geri dönen bir işlevdir int*
) iki veya bir kez üretilecektir.
Arasında eşdeğerlik x = x + y
ve x += y
nedeniyle özel durumda dolayısıyla olan +=
ve =
doğrudan L-değeri uygulanır.
Python'a geçmek için, C'nin sözdizimini miras aldı; ancak, yorumlanmış dillerde yürütmeden ÖNCE çeviri / optimizasyon olmadığından, işler mutlaka yakından ilişkili değildir (çünkü daha az bir ayrıştırma adımı vardır). Bununla birlikte, bir tercüman, ifadenin nasıl oluştuğuna ve değerlendirme bağlamına bağlı olarak farklı makine kodundan yararlanarak, üç ifade tipi için farklı yürütme rutinlerine başvurabilir.
Daha fazla ayrıntıyı sevenler için ...
Her CPU, özünde, girişleri ve çıktısı talimatların koduna bağlı olarak kayıt defterlerine ve / veya hafızaya "takılı" olan bir birleştirme ağına sahip olan bir ALU'ya (aritmetik-mantıksal birime) sahiptir.
İkili işlemler tipik olarak "bir yerde" girişi alınmış bir girişe sahip bir akümülatör kaydının değiştiricisi olarak gerçekleştirilir, burada bir yerde - komut akışının içinde (açık değişken için tipik: ADD A 5) - başka bir kayıt içinde (ifade hesaplaması için tipik geçici değerler: örn. ADD AB) - hafızanın içinde, bir yazmaç tarafından verilen adreste (tipik olarak veri toplama örneği: örn. ADD A (H)) - H, bu durumda bir referans gösterici gibi çalışır.
Bu sözde kod x += 5
ile
ADD (X) 5
süre x = x+5
olduğu
MOVE A (X)
ADD A 5
MOVE (X) A
Yani, x + 5, daha sonra atanacak bir geçici verir. x += 5
doğrudan x üzerinde çalışır.
Gerçek uygulama işlemcinin gerçek talimat setine bağlıdır: Eğer bir ADD (.) c
opcode yoksa, ilk kod ikinci olur: olmaz.
Böyle bir opcode varsa ve optimizasyon etkinleştirilirse, ikinci ifade, geriye doğru hareketleri ortadan kaldırdıktan ve kayıt opcode'unu ayarladıktan sonra, ilk ifadedir.
x += 5
dahax = x + 5
? Yoksa gerçekten önerdiğin gibi sadece sözdizimsel bir şeker mi?