Andrei'nin eniyileştirme üzerine konuşmasını izliyorum:
https://www.youtube.com/watch?v=ph7FP0LnmcA
İki noktayı denemek istedim:
-
32 bitlik veriyi yeğleyin çünkü 64 bitlik veriyi işlemekten daha hızlıdır (mantıklı)
-
Kesirli sayı bölme işlemi tamsayı bölme işleminden daha hızlıdır! (Bu çok şaşırtıcı ama nedenini duyunca o da mantıklı: kesirli sayının bellekteki gösteriminde değerin üssünü belirleyen bitlerde çıkartma işlemi yapmak yetiyor. (Tabii bunu mikro işlemci yapıyor.) Tamsayılarda ise mikro işlemci bütün bölme işlemini gerçekleştirmek zorunda.)
(Not: Sonuçlar sizin ortamınızda aynı çıkmayabilir.)
import std.stdio;
import std.algorithm;
import std.datetime;
import std.range;
import std.meta;
enum bölmeAdedi = 100_000;
enum testTekrarı = 100;
T dene(T)() {
T toplam = 42;
T bölen = 23;
bölmeAdedi.iota.each!(_ => toplam += toplam / bölen);
return toplam;
}
void main() {
foreach (T; AliasSeq!(byte, short, int, long,
ubyte, ushort, uint, ulong,
float, double /*, real HATALI SONUÇ VERİYOR */)) {
const ölçüm = benchmark!(() => cast(void)dene!T)(testTekrarı);
writefln("%10s: %8s", T.stringof, ölçüm[0].msecs);
}
}
Bu arada, real ile ilgili bir hata buldum ve bildirdim:
https://issues.dlang.org/show_bug.cgi?id=15466
Sonuç, hiç dmd seçeneği belirtmeden derleyince Andrei'nin dediği gibi çıkıyor (hepsi milisaniye):
'
byte: 204 <- int'ten yavaş çünkü işlemden önce int'e dönüştürülür
short: 203 <- aynı nedenden
int: 196 <- 32 bitlik veri daha hızlı
long: 297 <- 64 bitlik veri daha yavaş
ubyte: 202
ushort: 200
uint: 189
ulong: 253
float: 177 <- Evet, kesirli sayı daha hızlı
double: 176 <- Evet, kesirli sayı daha hızlı
'
dmd'ye bir de '-O -inline -noboundscheck -release' seçeneklerini vermeyi deniyorum. Çoğu derleyici gibi fazla akıllı davranıyor ve dene()'nin dönüş değerinin kullanılmadığını görerek o çağrıyı hiç yapmıyor ve sonuç her tür için 0 çıkıyor. O yüzden kodu biraz değiştiriyorum ve dene() artık sonuç döndürmüyor; parametresinde yan etki üretiyor.
Bu kod real kullanmadaki hatayı ortaya çıkartmadı onu da ekliyorum:
import std.stdio;
import std.algorithm;
import std.datetime;
import std.range;
import std.meta;
enum bölmeAdedi = 100_000;
enum testTekrarı = 100;
void dene(T)(ref T toplam) { // <-- toplam şimdi parametre olarak
T bölen = 23;
bölmeAdedi.iota.each!(_ => toplam += toplam / bölen);
}
void main() {
foreach (T; AliasSeq!(byte, short, int, long,
ubyte, ushort, uint, ulong,
float, double, real)) {
T toplam = 42; // <-- toplam şimdi parametre olarak
const ölçüm = benchmark!(() => dene!T(toplam))(testTekrarı);
writefln("%10s: %8s", T.stringof, ölçüm[0].msecs);
}
}
Şimdi sonuçlar daha çarpıcı:
'
byte: 99
short: 97
int: 111
long: 207
ubyte: 97
ushort: 98
uint: 107
ulong: 169
float: 58 <-- int'ten daha da hızlı :)
double: 57 <--
real: 1811 <-- artık hiç real kullanmasam mı? ;)
'
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]