Merhaba,
Gün geçmiyor ki insan yeni bir şey öğrenmesin. Şimdi nakledeceklerim basit şeyler ama sizi farklı düşünmeye sevk ediyor. Elbette günümüz işlemcileri için gereksiz olabilir; her şey eğitim için...
Önce 8 bölümlük kaynak vidyo:
Ve etkileyici ilk örneğimiz:
void toUpperASCII2(char[] str)
{
foreach(ref c; str)
{
c -= cast(char)(32 * (c >= 'a' && c <= 'z'));
}
}
Bu std.ascii
'de tek karakteri çeviren toUpper
'ın bir benzeri. Ama orada hem isLower
kullanılmış hem üçlü işleç ile klasik if/else mantığı var. Yoksa yine ASCII karakterden 32 çıkarılıyor...
Lütfen bir düşünün; verdiğim işlevi 1 milyon karakterli bir metni büyük harfe çevirmek için kullansanız, işlemciyi deli meşgul eder. Hatta bu sade görünen örneği, assembly kodunda daha iyi opimize edilen bir benzeri tavsiye ediliyor:
void toUpperASCII1(char[] str)
{
foreach(ref c; str)
{
c = cast(char)(( c * !(c >= 'a' && c <= 'z')) +
(c - 32) * (c >= 'a' && c <= 'z'));
}
}
Aradaki farka bakın ve sizin için 1 numara hangisi deneyip karar verin lütfen. Zaten kaynak vidyoda veya disassembly yaparsanız gerçek kodlarda bu farkı göreceksiniz...
Şimdi yine aynı mantıkla tasarlanan 2 minMax işlevi örneği vereceğim. Bu kaynaktaki ilk örnek ve eğer mantığı anlarsanız sadece matematiksel işlemler ile optimizasyon garanti.
int maxMin(int a, int b)
{
if(a < b)
return a;
else
return b;
}
int minMax(int a, int b)
{
return a * (a < b) + b * (b <= a);
}
unittest
{
int i = 3;
int j = 5;
assert(i.minMax(j) == i.maxMin(j));
import std.algorithm.mutation;
i.swap(j);
assert(i.minMax(j) == i.maxMin(j));
}
İlk işlev bizim her zaman yaptığımız klasik mantık. Tabi kodunuza uygunsa bunu ikinci işlevde olduğu gibi yapabilirsiniz. Farkettiyseniz dönen sonuçta da bir Boolean matematiği var. Ama dikkat, kodu disaasembling yaptığınızda dallanma komutları işleri karıştırıyor! Ne kadar -O2 gibi parametrelerle derlerseniz derleyin, sizin koda doğrudan yaptığınız optimizasyon kadar etkili olmayacaktır. Çünkü bütün bunlar domimant optimizasyonlar.
Başarılar...