C ++ düşük seviye optimizasyon ipuçları [kapalı]


79

Zaten en iyi seçim algoritmasına sahip olduğunuzu varsayarak, son birkaç tatlı tatlı kare hızını C ++ kodunun dışına sıkmak için hangi düşük seviyeli çözümleri sunabilirsiniz?

Bu ipuçlarının yalnızca profilinizde zaten vurguladığınız kritik kod bölümü için geçerli olduğunu belirtmeden devam eder, ancak bunlar düşük düzeyde yapısal olmayan iyileştirmeler olmalıdır. Bir örnek verdim.


1
Bunu bir oyun geliştirme sorusu yapan ve bunlar gibi genel bir programlama sorusu yapan şey değil: stackoverflow.com/search?q=c%2B%2B+optimization
Danny Varod

@ Danny - Bu muhtemelen genel bir programlama sorusu olabilir. Aynı zamanda oyunların programlanması ile ilgili bir sorudur. Bence bu iki sitede de geçerli bir soru.
Smashery,

@Smashery İkisi arasındaki tek fark oyun programlamanın belirli grafik motoru seviye optimizasyonları veya gölgelendirici kodlayıcı optimizasyonları gerektirebilmesidir, C ++ kısmı aynıdır.
Danny Varod

@Danny - Doğru, bazı sorular bir sitede ya da diğerinde alakalı "daha" olacaktır; ancak başka bir sitede de sorulabileceklerinden ilgili soruları reddetmek istemem.
Smashery

Yanıtlar:


76

Veri düzeninizi optimize edin! (Bu sadece C ++ 'dan daha fazla dil için geçerlidir)

Bunu, verilerinize, işlemcinize, çok çekirdekli bilgisayarları çok iyi bir şekilde ele almaya, vb. Göre özel olarak ayarlayarak oldukça derine gidebilirsiniz. Ama temel kavram şudur:

Sıkı bir döngüde işleri işlerken, her yineleme için verileri olabildiğince küçük ve bellekte olabildiğince birbirine yakın hale getirmek istiyorsunuz. Bu, idealin yalnızca hesaplama için gerekli verileri içeren bir dizi veya nesne (işaretçiler değil) olduğu anlamına gelir.

Bu şekilde, CPU, döngünüzün ilk yinelemesine ilişkin verileri getirdiğinde, sonraki birkaç veri yinelemesi, onunla birlikte önbelleğe yüklenir.

Gerçekten CPU hızlı ve derleyici iyi. Daha az ve daha hızlı talimatlar kullanarak yapabileceğiniz pek bir şey yok. Önbellek tutarlılığı nerededir (bu, Googled'in rastgele bir makalesidir - basitçe verileri doğrusal bir şekilde çalıştıran bir algoritma için önbellek tutarlılığını elde etmek için iyi bir örnek içerir).


Bağlantılı Önbellek tutarlılığı sayfasında C örneğini denemeye değer. Bunu ilk öğrendiğimde ne kadar fark yarattığı konusunda şok oldum.
Neel,

9
Ayrıca bkz. Mükemmel Nesne Yönelimli Programlama Sunumları Tuzakları sunumu (Sony R&D) ( research.scee.net/files/presentations/gcapaustralia09/… ) - ve Mike Acton'un huysuz ama etkileyici CellPerformance makaleleri ( cellperformance.beyond3d.com/articles/ index.html ). Noel Llopis'in Blog'daki Oyunları da bu konuya sıkça değiniyor ( gamesfromwithin.com ). Tuzaklar yeterince slaytlar tavsiye edemez ...
leander

2
"Her yineleme için verileri olabildiğince küçük ve bellekte olabildiğince yakın" yapmak konusunda uyardım . Hizalanmamış verilere erişmek işleri daha yavaş hale getirebilir; bu durumda dolgu maddesi daha iyi performans verecektir. Veri sırası da önemlidir, ayrıca sipariş edilen veriler daha az dolmaya neden olabilir. Scott Mayers bunu, benden daha iyi açıklayabilir :)
Jonathan Connell,

Sony sunumuna +1. Bunu daha önce okudum ve verilerin topaklara bölünmesi ve düzgün şekilde hizalanması dikkate alınarak platform düzeyinde verinin nasıl optimize edileceği gerçekten mantıklı geliyor.
ChrisC

84

Çok, çok düşük seviyeli bir ipucu ama kullanışlı bir ipucu:

Derleyicilerin çoğu, bir takım açık koşullu ipuçlarını destekler. GCC, __builtin_expect adlı bir işleve sahiptir ve bu da derleyiciye bir sonucun değerini tahmin etmenizi sağlar. GCC, bu verileri, beklenilen durumda beklenmeyen durumda biraz daha yavaş yürütme ile beklenen durumda mümkün olan en hızlı şekilde çalışacak şekilde optimize etmek için kullanabilir.

if(__builtin_expect(entity->extremely_unlikely_flag, 0)) {
  // code that is rarely run
}

Bunun doğru kullanımı ile% 10-20'lik bir hızlanma gördüm.


1
Yapabilseydim iki kere oy kullanırdım.
tenpn

10
+1, Linux çekirdeği bunu zamanlayıcı kodundaki mikro optimizasyonlar için yaygın olarak kullanıyor ve belirli kod yollarında önemli bir fark yaratıyor.
greyfade

2
Ne yazık ki, Visual Studio'da iyi bir eşdeğer yok gibi görünüyor. stackoverflow.com/questions/1440570/…
mmyers

1
Peki, hangi sıklıkta beklenen değer genellikle performans elde etmek için doğru değer olmak zorundadır? 49/50 kere mi? Veya 999999/1000000 kez?
Douglas

36

Anlamanız gereken ilk şey, üzerinde çalıştığınız donanımdır. Dallara nasıl müdahale eder? Önbelleğe almaya ne dersin? SIMD komut seti var mı? Kaç tane işlemci kullanabilir? İşlemci zamanını başka bir şeyle paylaşmak zorunda mı?

Aynı problemi çok farklı şekillerde çözebilirsiniz - algoritma seçiminiz bile donanıma bağlı olmalıdır. Bazı durumlarda O (N), O'dan (NlogN) daha yavaş çalışabilir (uygulamaya bağlı olarak).

Optimizasyona kaba bir bakış olarak, yapacağım ilk şey tam olarak hangi problemlere ve hangi verileri çözmeye çalıştığınıza bakmaktır. Sonra bunun için optimize edin. Aşırı performans istiyorsanız, genel çözümleri unutun; en çok kullandığınız durumla uyuşmayan her şeyi özel olarak yapabilirsiniz.

Ardından profil. Profil, profil, profil. Bellek kullanımına bakın, dallanma cezalarına bakın, genel fonksiyon çağrısına bakın, boru hattı kullanımına bakın. Kodunuzu yavaşlatan şeyin ne olduğunu öğrenin. Muhtemelen veri erişimidir (Veri erişiminin ek yükü hakkında "Gecikme Fil" adlı bir makale yazdım - google bunu yazdı. Burada "bağlantı" yeterli olmadığı için 2 bağlantı gönderemiyorum), daha sonra veri düzeninizi optimize edin ( homojen düz diziler harika, harika ) ve veri erişimini (mümkün olan yerlerde önceden alma).

Bellek alt sisteminin yükünü en aza indirdikten sonra, talimatların şimdi tıkanıklık olup olmadığına karar verin (umarım onlardır), ardından algoritmanızın SIMD uygulamalarına bakın - Dizilerin Yapısı (SoA) uygulamaları çok veri olabilir ve Öğretim önbelleği verimli. SIMD probleminiz için uygun değilse, gerçek ve montaj seviyesi kodlaması gerekebilir.

Hala daha fazla hıza ihtiyacınız varsa paralel gidin. PS3'te yayın yapma avantajınız varsa, SPU'lar arkadaşlarınızdır. Onları kullan, onları sev. Zaten bir SIMD çözümü yazdıysanız, SPU’ya geçerken büyük bir avantaj elde edersiniz.

Ve sonra, biraz daha profil. Oyun senaryolarında test et - bu kod hala darboğaz mı? Kullanımını en aza indirmek için bu kodun kullanılma şeklini değiştirebilir misiniz (aslında, bu ilk adımınız olmalıdır)? Hesaplamaları birden fazla çerçeve üzerinden erteleyebilir misiniz?

Hangi platformda olursanız olun, donanım ve mevcut profilerler hakkında mümkün olduğunca çok şey öğrenin. Darboğazın ne olduğunu bildiğinizi sanmayın - bunu profilcinizde bulun. Ve oyununuzu gerçekten daha hızlı yapıp yapmadığınızı belirlemek için bir sezgisel buluşma yaptığınızdan emin olun.

Ve sonra tekrar profil.


31

İlk adım: Algoritmalarınızla ilgili verilerinizi dikkatlice düşünün. O (log n) her zaman O (n) 'den daha hızlı değildir. Basit örnek: Yalnızca birkaç tuşa sahip bir karma tablo genellikle doğrusal bir aramayla yerine daha iyi yerleştirilir.

İkinci adım: Üretilen düzeneğe bakın. C ++, tabloya bir çok örtük kod üretimi getiriyor. Bazen, bilmeden sana gizlice giriyor.

Ancak metal pedalı için gerçekten iyi bir zaman olduğunu varsayarsak: Profil. Ciddi anlamda. Rastgele "performans hileleri" uygulamak, yardımcı olabileceği kadar zarar verebilir.

O zaman, her şey darboğazlarınızın ne olduğuna bağlı.

veri önbelleği özlüyor => veri düzeninizi optimize edin. İşte güzel bir başlangıç ​​noktası: http://gamesfromwithin.com/data-oriented-design

kod önbelleği özlüyor => Sanal işlev aramalarına, aşırı arama derinliğine vb. bakın. Kötü performansın yaygın bir nedeni, temel sınıfların sanal olması gerektiğine dair hatalı bir inançtır .

Diğer yaygın C ++ performans lavaboları:

  • Aşırı tahsis / tahsisat Performans kritikse, çalışma zamanını aramayın. Hiç.
  • Yapıyı kopyala. Nerede olursanız olun kaçının. Bir const referans olabilirse, bir tane yapın.

Yukarıdakilerin hepsi derleme baktığınızda hemen açıktır, bu yüzden yukarıya bakın;)


19

Gereksiz dalları kaldırın

Bazı platformlarda ve bazı derleyicilerde dallar tüm boru hattınızı atabilir, böylece eğer () blokları pahalı olabilirse önemsiz olabilir.

PowerPC mimarisi (PS3 / x360) kayan nokta seçme talimatını sunar fsel,. Bloklar basit ödevler ise, bir şubenin yerine kullanılabilir:

float result = 0;
if (foo > bar) { result = 2.0f; }
else { result = 1.0f; }

Oluyor:

float result = fsel(foo-bar, 2.0f, 1.0f);

İlk parametre 0'dan büyük veya ona eşit olduğunda, ikinci parametre, üçüncü ise geri döndürülür.

Şubeyi kaybetmenin bedeli hem if {} hem de {} bloğunun çalıştırılacağıdır, bu nedenle eğer pahalı bir işlem veya bir NULL işaretçisi varsa, bu optimizasyon uygun değildir.

Bazen derleyiciniz bu işi zaten yaptı, bu yüzden önce montajınızı kontrol edin.

Dallanma ve yanılma hakkında daha fazla bilgi:

http://assemblyrequired.crashworks.org/tag/intrinsics/


şamandıra sonucu = (foo> bar)? 2.f: 1.f
knight666

3
@ knight666: Hala, "if" in yapacağı her yerde bir dal üretecek. Öyle söylüyorum çünkü en azından, böyle küçük diziler dallanma gerektirmeyen şartlı talimatlarla uygulanabilir.
chrisbtoo

1
@ knight666 eğer şanslıysanız, derleyici bunu bir hataya dönüştürebilir, ancak kesin değil. FWIW, normalde bu snippet'i üçüncül bir operatörle yazacağım ve daha sonra profiler kabul ederse daha sonra fsellemeyi optimize etmek için yazacağım.
tenpn,

IA32'de bunun yerine CMOVcc var.
Skizz

Ayrıca bkz. Blueraja.com/blog/285/… (bu durumda, derleyici herhangi bir sorun çıkarsa, bunun kendisini en iyi duruma getirebilmesi gerektiğine dikkat edin, bu nedenle normalde endişelenmeniz gereken bir şey değildir)
BlueRaja - Danny Pflughoeft

16

Her ne pahasına olursa olsun hafıza erişiminden ve özellikle de rastgele erişimden kaçının.

Modern işlemciler için optimize etmek için en önemli şey budur. RAM'den veri beklerken çok fazla aritmetik ve hatta çok fazla yanlış tahmin edilmiş dal bile yapabilirsiniz.

Bu kuralı diğer yollarla da okuyabilirsiniz: Bellek erişimleri arasında mümkün olduğunca fazla hesaplama yapın.



11

Gereksiz sanal işlev çağrılarını kaldırın

Sanal bir işlevin gönderilmesi çok yavaş olabilir. Bu makale nedeninin iyi bir açıklamasını verir. Mümkünse, kare başına birçok kez çağrılan işlevler için, bunlardan kaçının.

Bunu birkaç yolla yapabilirsiniz. Bazen, sınıfları miras almanıza gerek kalmayacak şekilde yeniden yazabilirsiniz - belki de MachineGun’un Silah’ın tek alt sınıfı olduğu ortaya çıktı ve onları birleştirebilirsiniz.

Çalışma zamanı polimorfizmini derleme zamanı polimorfizmi ile değiştirmek için şablonlar kullanabilirsiniz. Bu, yalnızca çalışma zamanında nesnelerinizin alt türünü biliyorsanız ve büyük bir yeniden yazma olabilirse çalışır.


9

Temel prensibim: gerekli olmayan hiçbir şey yapmayın .

Belirli bir işlevin bir tıkanıklık olduğunu tespit ettiyseniz, işlevi en iyi duruma getirebilir - ya da ilk başta çağrılmasını engellemeye çalışabilirsiniz.

Bu mutlaka kötü bir algoritma kullandığınız anlamına gelmez. Bu, örneğin kısa bir süre için önbelleğe alınabilecek her kareyi (veya tamamen önceden hesaplanmış) hesaplamaları çalıştırdığınız anlamına gelebilir.

Her zaman bu yaklaşımı gerçekten düşük seviye optimizasyon denemelerinden önce deniyorum.


2
Bu soru zaten yapabileceğiniz tüm yapısal işleri yaptığınızı varsayıyor.
tenpn,

2
Öyle. Fakat çoğu zaman sahip olduğunuzu ve sahip olmadığınızı varsayarsınız. Gerçekten de, pahalı bir fonksiyonun optimize edilmesi gerektiğinde, bu fonksiyonu çağırmanız gerekip gerekmediğini kendinize sorun.
Rachel Blum

2
... ama bazen, sonucu daldan ziyade atacak olsanız bile hesaplamayı yapmak daha hızlı olabilir.
tenpn

9

Henüz yapmadıysanız, SIMD (SSE tarafından) kullanın. Gamasutra'nun bu konuda güzel bir makalesi var . Kaynak kodunu makalenin sonunda sunulan kitaplıktan indirebilirsiniz.


6

CPU boru hattını daha iyi kullanmak için bağımlılık zincirlerini en aza indirin.

Basit durumlarda, döngü açmayı etkinleştirirseniz, derleyici bunu sizin için yapabilir. Ancak çoğu zaman bunu yapmaz, özellikle de ifadeleri yeniden düzenlemekle ilgili olan değişkenler olduğunda sonucu değiştirir.

Örnek:

float *data = ...;
int length = ...;

// Slow version
float total = 0.0f;
int i;
for (i=0; i < length; i++)
{
  total += data[i]
}

// Fast version
float total1, total2, total3, total4;
for (i=0; i < length-3; i += 4)
{
  total1 += data[i];
  total2 += data[i+1];
  total3 += data[i+2];
  total4 += data[i+3];
}
for (; i < length; i++)
{
  total += data[i]
}
total += (total1 + total2) + (total3 + total4);

4

Derleyicinizi gözden kaçırmayın - Intel'de gcc kullanıyorsanız, örneğin Intel C / C ++ Derleyicisine geçerek kolayca performans elde edebilirsiniz. Bir ARM platformunu hedefliyorsanız, ARM'ın ticari derleyicisini inceleyin. İPhone'daysanız, Apple ilang 4.0 SDK ile başlayan Clang'ın kullanılmasına izin verdi.

Özellikle x86'da optimizasyonla karşılaşacağınız bir sorun, modern CPU uygulamalarında size karşı bir çok sezgisel işin sonuçlanmasıdır. Ne yazık ki çoğumuz için, derleyiciyi en iyi duruma getirme yeteneği çoktan geride kaldı. Derleyici, kendi CPU bilgisine dayanarak akıştaki talimatları zamanlayabilir. Ek olarak, CPU kendi gereksinimlerine göre talimatları yeniden planlayabilir. Bir yöntemi düzenlemenin en uygun yolunu bulsanız bile, derleyici veya CPU zaten kendi başına geldi ve bu optimizasyonu zaten gerçekleştirdi.

En iyi tavsiyem, düşük seviyeli optimizasyonları göz ardı etmek ve daha üst seviyelere odaklanmaktır. Derleyici ve CPU, ne kadar iyi olursa olsun algoritmasını O (n ^ 2) 'den O (1) algoritmasına değiştiremez. Bu tam olarak ne yapmaya çalıştığınıza bakmanızı ve daha iyi bir yol bulmanızı gerektirir. Derleyici ve CPU'nun düşük seviye için endişelenmesine izin verin; orta ila yüksek seviyelere odaklanın.


Ne dediğinizi anlıyorum ama O (logN) 'a ulaştığınızda ve düşük seviye optimizasyonların devreye girip sizi kazanabileceği yapısal değişikliklerden daha fazla yararlanamayacağınız bir nokta var bu ekstra yarım milisaniye.
tenpn

1
Cevabımı bakın re: O (log n). Ayrıca, yarım milisaniye ararsanız, daha yüksek seviyeye bakmanız gerekebilir. Bu sizin çerçeve zamanınızın% 3'ü!
Rachel Blum

4

Kısıtlamak kelime özellikle işaretçileri ile nesneleri işlemek için gereken hallerde, potansiyel olarak kullanışlıdır. Derleyicinin sivri uçlu nesnenin başka bir şekilde değiştirilmeyeceğini varsaymasına izin verir, bu da nesnenin parçalarını sicillerde tutmak veya daha etkin bir şekilde okuma ve yazma gibi daha agresif bir optimizasyon gerçekleştirmesine izin verir.

Anahtar kelime ile ilgili iyi bir şey, bir kez uygulayabileceğiniz ve algoritmanızı yeniden düzenlemeden faydalarını görebileceğiniz ipucudur. Kötü tarafı, yanlış yerde kullanırsanız, veri bozulmalarını görmenizdir. Ancak, genellikle onu kullanmanın meşru olduğu yeri bulmak oldukça kolaydır - programcının derleyicinin güvenli bir şekilde kabul edebileceğinden daha fazlasını bilmesi beklenebilecek birkaç örnekten biridir, bu yüzden anahtar kelimenin kullanılmasının nedeni budur.

Teknik olarak 'kısıtlama' standart C ++ 'da yoktur, ancak çoğu C ++ derleyicileri için platforma eşdeğer eşdeğerleri mevcuttur, bu yüzden dikkate değer.

Ayrıca bakınız: http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html


2

Const herşey!

Derleyiciye veriler hakkında ne kadar fazla bilgi verirseniz, optimizasyonlar da o kadar iyi olur (en azından benim deneyimime göre).

void foo(Bar * x) {...;}

olur;

void foo(const Bar * const x) {...;}

Derleyici, x göstergesinin değişmeyeceğini ve işaret ettiği verinin de değişmeyeceğini biliyor.

Diğer bir ek fayda ise, yanlışlıkla oluşmaması gereken şeyleri değiştirerek kendinizi (veya başkalarını) durdurarak, yanlışlıkla yapılan böcek sayısını azaltabileceğinizdir.


Ve kod arkadaşın seni sevecek!
tenpn

4
constderleyici optimizasyonlarını iyileştirmez. Bir değişkenin değişmeyeceğini bildiği halde derleyicinin daha iyi kod üretebileceği, ancak constyeterince güçlü bir garanti sağlamadığı doğru.
deft_code

3
Hayır! “kısıtla”, “const” dan çok daha faydalıdır. Bakınız gamedev.stackexchange.com/questions/853/…
Justicle

+1 ppl const yardım edemem
NoSenseEtAl 01:14 'de

2

Çoğu zaman, performans kazanmanın en iyi yolu algoritmanızı değiştirmektir. Uygulama ne kadar az genel olursa metale o kadar yaklaşırsınız.

Bunun yapıldığını varsayarak ....

Eğer gerçekten kritik bir kodsa, hafıza okumalarını önlemeye çalışın, önceden hesaplanabilecek şeyleri hesaplamaktan kaçının (kural numarası 1'i ihlal ettiği için arama tabloları olmasa da). Algoritmanızın ne yaptığını bilin ve derleyicinin de bildiği şekilde yazın. Yapıldığından emin olmak için montajı kontrol edin.

Önbellek eksikliğinden kaçının. Toplu işlem mümkün olduğunca. Sanal işlevlerden ve diğer indirmelerden kaçının.

Sonuçta, her şeyi ölçün. Kurallar her zaman değişir. 3 yıl önce kodu hızlandırmak için kullanılanlar şimdi yavaşlatıyor. Güzel bir örnek 'şamandıra sürümleri yerine çift matematik fonksiyonlarını kullanın'. Bunu okumamış olsaydım, bunu fark etmezdim.

Unuttum - varsayılan kurucu değişkenlerinize ağırlık vermeyin ya da ısrar ederseniz, en azından yapmayan kurucular da yaratın. Profillerde görünmeyen şeylerin farkında olun. Gereksiz kod döngüsü başına bir döngü kaybederseniz, profilinizde hiçbir şey görünmez, ancak genel olarak bir sürü döngü kaybedersiniz. Yine, kodunuzun ne yaptığını bilin. Çekirdek işlevinizi kusursuz yerine yalın yapın. Gerekirse kusursuz sürümler çağrılabilir, ancak her zaman gerekli değildir. Çok yönlülük bir bedelle gelir - performans birdir.

Varsayılan başlatma yok nedenini açıklamak için düzenlenmiştir: Bir çok kod diyor ki: Vector3 bla; bla = DoSomething ();

Yapıcıdaki intializasyon zaman kaybıdır. Ayrıca, bu durumda boşa harcanan zaman çok küçüktür (muhtemelen vektörü temizler), ancak programcılarınız bunu alışkanlık olarak yaparsa ekler. Ayrıca, birçok işlev, sıfıra başlatılan ve hemen sonra atanan geçici (aşırı yüklenmiş operatörleri düşünür) oluşturur. Profilcinizde çiviyi göremeyecek kadar küçük olan gizli kayıp çevrimler, ancak kod tabanınızın her tarafında taşan döngüleri. Ayrıca, bazı insanlar yapıcılarda çok daha fazlasını yapar (ki bu kesinlikle hayır). Yapıcının ağır tarafında biraz olduğu, kullanılmayan bir değişkenden çok milisaniyelik kazançlar elde ettim. Yapıcı yan etkilere neden olur olmaz, derleyici onu dışa aktaramaz, bu yüzden yukarıdaki kodu hiçbir zaman kullanmazsanız, başlatıcı olmayan bir yapıcıyı ya da dediğim gibi

Vector3 bla (noInit); bla = doSomething ();


/ Üyelerinizi kurucuda başlatmıyor musunuz? Bu nasıl yardımcı olur?
tenpn

Düzenlenmiş gönderiye bakın. Yorum kutusuna sığmadı.
Kaj

const Vector3 = doSomething()? O zaman geri dönüş değeri optimizasyonu devreye girebilir ve muhtemelen bir veya iki ödev yaratabilir.
saat

1

Boole ifadesi değerlendirmesini azalt

Bu çok çaresiz, çünkü kodunuzda çok ince ama tehlikeli bir değişiklik. Ancak, hatalı sayıda değerlendirilen bir koşulunuz varsa, bunun yerine bitsel işleçleri kullanarak boole değerlendirmesinin ek yükünü azaltabilirsiniz. Yani:

if ((foo && bar) || blah) { ... } 

Oluyor:

if ((foo & bar) | blah) { ... }

Bunun yerine tamsayı aritmetik kullanma. Foos ve barlarınız if () 'den önce sabitse veya değerlendirilirse, bu normal boolean versiyonundan daha hızlı olabilir.

Bonus olarak, aritmetik sürüm normal boolean sürümden daha az dallıdır. Optimize etmek için başka bir yoludur .

Büyük dezavantajı tembel değerlendirme kaybedersiniz - tüm blok değerlendirilir, bu yüzden yapamazsınız foo != NULL & foo->dereference(). Bu nedenle, bunun sürdürülmesinin zor olduğu ve bu yüzden takasın çok büyük olabileceği tartışılabilir.


1
Bu, performans uğruna oldukça korkunç bir takas, çünkü bunun amaçlandığı hemen belli değil.
Bob Somers,

Sana neredeyse tamamen katılıyorum. Çaresiz olduğunu söyledim!
tenpn,

3
Bu aynı zamanda kısa devreyi kırmak ve şube tahminini daha güvenilir hale getirmez mi?
Egon,

1
Foo 2 ve bar 1 ise, kod aynı şekilde davranmaz. Bu ve erken değerlendirme değil, sanırım en büyük dezavantajı.

1
Gerçekte, C ++ 'daki boole'lar 0 veya 1 olarak garanti edilir, bu yüzden sadece güvende olduğunla bunu yapıyorsun. Daha fazla: altdevblogaday.org/2011/04/18/understanding-your-bool-type
tenpn

1

Yığın kullanımınıza bir göz atın

Yığına eklediğiniz her şey, bir işlev çağrıldığında fazladan bir itme ve yapıdır. Büyük miktarda yığın alanı gerektiğinde, bazen çalışma belleğini önceden ayırmak yararlı olabilir ve üzerinde çalıştığınız platformun kullanım için hızlı RAM'i varsa, hepsinden iyisi!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.