Hayır, ama evet, ama belki, ama belki başka bir yol, ama hayır.
İnsanların daha önce işaret ettiği gibi, (eklemenin C, C ++, C # veya Java gibi sol ilişkisel olduğu bir dil varsayarsak) ifadenin ((1 + 2) + 3)
tam olarak eşdeğerdir 1 + 2 + 3
. Kaynak kodda, sonuçtaki makine kodu veya bayt kodu üzerinde sıfır etkisi olacak bir şey yazmanın farklı yollarıdır.
Her iki durumda da sonuç, örneğin iki kayıt eklemek ve daha sonra bir üçüncü eklemek veya bir yığından iki değer almak, eklemek, geri itmek, sonra diğerini almak ve eklemek ya da üç kayıt eklemek için bir talimat olacaktır. tek bir işlem veya bir sonraki düzeyde neyin en duyarlı olduğuna bağlı olarak üç sayıyı toplamak için başka bir yol (makine kodu veya bayt kodu). Bayt kodu durumunda, bu muhtemelen benzer bir yeniden yapılandırmaya tabi tutulacaktır, örneğin bunun IL eşdeğeri (bir yığına bir dizi yük olacak ve sonucu eklemek ve sonra geri itmek için haşhaş çiftleri olacaktır) bu mantığın makine kodu düzeyinde doğrudan bir kopyasıyla sonuçlanmaz, ancak söz konusu makine için daha mantıklı bir şeyle sonuçlanır.
Ama sorunuzda daha fazlası var.
Herhangi bir aklı başında C, C ++, Java veya C # derleyicisi olması durumunda, verdiğiniz ifadelerin her ikisinin sonucunun tam olarak aynı sonuçlara sahip olmasını beklerim:
int a = 6;
Sonuçta ortaya çıkan kod neden hazır bilgi üzerinde matematik yapmak için zaman kaybetmeli? Programın durumunda hiçbir değişiklik 1 + 2 + 3
olmanın sonucunu durduramaz 6
, bu yüzden yürütülmekte olan kodda ne olması gerekir. Gerçekten de, belki de (bu 6 ile ne yaptığınıza bağlı olarak, belki de her şeyi atabiliriz) ve C # felsefesi ile "yoğun bir şekilde optimize etmeyin, çünkü yine de jitter bunu optimize edecektir" eşdeğeri int a = 6
ya da sadece gereksiz her şeyi atmak).
Yine de bu bizi sorunuzun olası bir uzantısına götürür. Aşağıdakileri göz önünde bulundur:
int a = (b - 2) / 2;
/* or */
int a = (b / 2)--;
ve
int c;
if(d < 100)
c = 0;
else
c = d * 31;
/* or */
int c = d < 100 ? 0 : d * 32 - d
/* or */
int c = d < 100 && d * 32 - d;
/* or */
int c = (d < 100) * (d * 32 - d);
(Bu son iki örnek geçerli C # değildir, burada her şey geçerlidir ve C, C ++ ve Java için geçerlidir.)
Burada yine çıktı açısından tam olarak eşdeğer bir kod var. Sabit ifadeler olmadıkları için derleme zamanında hesaplanmazlar. Bir formun diğerinden daha hızlı olması mümkündür. Hangisi daha hızlı? Bu işlemciye ve belki de durumdaki bazı keyfi farklılıklara bağlı olacaktır (özellikle biri daha hızlıysa, çok daha hızlı olması muhtemel değildir).
Ve bunlar, çoğunlukla bir şeyin kavramsal olarak yapıldığı sıradaki farklarla ilgili olduğu için, sorunuzla tamamen alakasız değildir .
Her birinde, birinin diğerinden daha hızlı olabileceğinden şüphelenmek için bir neden var. Tek düşüşlerin özel bir talimatı (b / 2)--
olabilir , bu yüzden gerçekten daha hızlı olabilir (b - 2) / 2
. d * 32
belki daha hızlı dönüştürerek üretilen olabilir d << 5
yapım böylece d * 32 - d
daha hızlı d * 31
. Son ikisi arasındaki farklar özellikle ilginçtir; bir tanesi bazı durumlarda bazı işlemlerin atlanmasına izin verirken diğeri dalın yanlış tahmin olasılığını ortadan kaldırır.
Yani, bu bize iki soru bırakıyor: 1. Biri diğerinden daha hızlı mı? 2. Bir derleyici daha yavaş olanı daha hızlıya çevirir mi?
Ve cevap 1'dir. 2. Belki.
Veya genişletmek için, söz konusu işlemciye bağlı olduğu için bağlıdır. Kuşkusuz, birinin saf makine kodu eşdeğerinin diğerinin saf makine kodu eşdeğerinden daha hızlı olacağı işlemciler vardır. Elektronik bilgi işlem tarihi boyunca, her zaman daha hızlı olan bir tane de yoktu (özellikle dal yanlış tahmin öğesi, boru hattı olmayan CPU'lar daha yaygın olduğunda birçok kişi için geçerli değildi).
Ve belki de, derleyicilerin (ve titremelerin ve komut dosyası motorlarının) yapacağı bir dizi farklı optimizasyon olduğundan ve bazıları belirli durumlarda zorunlu kılınsa da, genellikle mantıksal olarak eşdeğer bazı kod parçaları bulabiliriz. en saf derleyici bile tam olarak aynı sonuçlara ve mantıksal olarak eşdeğer bazı kodlara sahiptir, burada en sofistike olanlar bile diğerine göre daha hızlı kod üretir (sadece amacımızı kanıtlamak için tamamen patolojik bir şey yazsak bile).
Çok küçük bir optimizasyon endişesi gibi görünebilir,
Hayır. Burada verdiğimden daha karmaşık farklılıklarla bile, optimizasyonla ilgisi olmayan kesinlikle küçük bir endişe gibi görünüyor. Eğer bir şey varsa, bu bir karamsarlık meselesidir, çünkü okumamanın daha zor olması, okunması ((1 + 2) + 3
daha kolay olandan daha yavaş olabilir 1 + 2 + 3
.
ancak C # / Java / ... üzerinden C ++ seçimi tamamen optimizasyon (IMHO) ile ilgilidir.
C # veya Java üzerinden C ++ seçmenin "hepsi hakkında" olması buysa, insanların Stroustrup ve ISO / IEC 14882 kopyalarını yazmaları ve C ++ derleyicilerinin alanlarını boşaltmaları ve daha fazla MP3 veya başka bir şey için yer bırakmaları gerektiğini söyleyebilirim.
Bu diller birbirinden farklı avantajlara sahiptir.
Bunlardan biri, C ++ 'ın bellek kullanımında hala daha hızlı ve daha hafif olmasıdır. Evet, C # ve / veya Java'nın daha hızlı olduğu ve / veya uygulama ömrü boyunca bellek kullanımının daha iyi olduğu örnekler vardır ve bunlar ilgili teknolojiler geliştikçe daha yaygın hale gelir, ancak yine de C ++ ile yazılmış ortalama programın işini daha hızlı yapan ve bu iki dilde eşdeğerden daha az bellek kullanan daha küçük bir yürütülebilir dosya.
Bu bir optimizasyon değil.
Optimizasyon bazen "işleri hızlandırmak" için kullanılır. Bu anlaşılabilir bir durumdur, çünkü çoğu zaman gerçekten "optimizasyon" dan bahsettiğimizde, gerçekten işleri daha hızlı hale getirmekten bahsediyoruz ve bu yüzden biri diğeri için bir kısayol haline geldi ve kelimeyi kendim bu şekilde kötüye kullandığımı itiraf edeceğim.
"İşleri daha hızlı hale getirmek" için doğru kelime optimizasyon değildir . Buradaki doğru kelime iyileştirmedir . Bir programda değişiklik yaparsanız ve tek anlamlı fark, artık daha hızlı olması, hiçbir şekilde optimize edilmemesi, sadece daha iyi olmasıdır.
Optimizasyon , belirli bir yön ve / veya özel durumla ilgili bir iyileştirme yaptığımız zamandır. Ortak örnekler:
- Artık bir kullanım durumu için daha hızlı, diğeri için daha yavaş.
- Şimdi daha hızlı, ancak daha fazla bellek kullanıyor.
- Artık bellekte daha hafif, ancak daha yavaş.
- Şimdi daha hızlı, ancak bakımı daha zor.
- Artık bakımı daha kolay, ancak daha yavaş.
Bu gibi durumlar, örneğin:
- Daha hızlı kullanım durumu, daha yaygın veya daha ciddi şekilde engellenir.
- Program kabul edilemez derecede yavaştı ve çok fazla RAM kullanmıyoruz.
- Program durma noktasına geliyordu, çünkü çok fazla RAM kullandı, süper hızlı işlemesini gerçekleştirmekten daha fazla zaman harcadı.
- Program kabul edilemez derecede yavaştı ve kodun anlaşılması daha iyi belgelenmiş ve nispeten kararlı.
- Program hala kabul edilebilir derecede hızlıdır ve daha anlaşılır kod tabanının bakımı daha ucuzdur ve diğer geliştirmelerin daha kolay yapılmasına izin verir.
Ancak, bu gibi durumlar diğer senaryolarda da haklı görülmeyecektir: Kod, mutlak yanılmaz bir kalite ölçüsü ile daha iyi hale getirilmemiştir, belirli bir kullanım için daha uygun hale getiren belirli bir açıdan daha iyi hale getirilmiştir; Optimize edilmiş.
Ve burada dil seçiminin bir etkisi var, çünkü hız, bellek kullanımı ve okunabilirlik bundan etkilenebilir, ancak diğer sistemlerle uyumluluk, kütüphanelerin kullanılabilirliği, çalışma zamanlarının kullanılabilirliği, belirli bir işletim sisteminde bu çalışma zamanlarının olgunluğu da olabilir (günahlarım için bir şekilde en sevdiğim işletim sistemleri olarak Linux ve Android'e ve en sevdiğim dil olarak C # 'a sahip oldum ve Mono harika olsa da, yine de buna karşı geliyorum).
"C # / Java / ... üzerinden C ++ seçimi tüm optimizasyonlarla ilgilidir" demek sadece C ++ 'ın gerçekten berbat olduğunu düşünüyorsanız mantıklıdır, çünkü optimizasyon "daha iyi ..." değil, "daha iyi" değil. C ++ 'ın kendisine rağmen daha iyi olduğunu düşünüyorsanız, ihtiyacınız olan son şey mümkün olan en kısa mikro-seçimler hakkında endişelenmektir. Gerçekten de, muhtemelen onu terk etmekten daha iyidir; mutlu hackerlar da optimize etmek için bir kalite!
Bununla birlikte, "C ++ 'ı seviyorum ve bununla ilgili sevdiğim şeylerden biri ekstra döngüleri sıkmak" demeye meyilliyseniz, bu farklı bir konudur. Hala mikro-ops'ların sadece refleksif bir alışkanlık olabilmeleri durumunda buna değer olduğu bir durumdur (yani, doğal olarak kodlama eğiliminiz yavaş olandan daha hızlı olacaktır). Aksi takdirde erken optimizasyon bile değiller, işleri daha da kötüleştiren erken karamsarlık.