Thread overview
endl vs \n [C++]
Apr 23, 2011
erdem
Apr 23, 2011
erdem
April 23, 2011

Aslında C++ ile uğraştığım söylenemez :-D Ama bir forumda benim de işin içinden çıkamadığım bir soru geldi.

Örneğin şu ikisinin aynı olduğunu biliyoruz.


   cout << "birseyler" << endl;


   cout << "birseyler" << '\n' << flush;

Hatta C++ FAQ Lite'de:

[15.7] Should I end my output lines with std::endl or '\n'? (http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.7)

çoğu durumda performans açısından 'endl' yerine '\n' kullanılması tavsiye ediliyor.

#include <iostream>
#include <fstream>

using namespace std;

int main() {
   ofstream cikisAkimi("alfabe.txt", ios::out);

   for (char harf = 'A'; harf <= 'Z'; ++harf) {
       cikisAkimi << harf << endl;
   }

   return 0;
}

Örneğin yukarıdaki programda gereksiz yere 26 kere 'std::flush' çağrılıyor. Ama '\n' kullansaydık sadece bir kere program sonlandırılırken çıkış akımının belleği ekrana yazılacaktı.

Benim merak ettiğim her 'flush' ile beraber 26 kere dosya da açılırmı? Ayrıca 'endl' ve '\n' in performans olarak karşılaştırmasını gösteren gerçek bir örnek nasıl yazabiliriz? Eğer ciddi olarak bir performans farkı varsa.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 23, 2011

D'de umarım böyle şeylere ihtiyaç duymayız :-D

Gerçekten D'ye alışınca C++ bile biraz ''? '!' :-/ gelmeye başladı :)

Ben de ilk verdiğim örnekte dosyaya 1.000.000 sayı yazdırınca 4 saniyelik bir fark oluştuğunu farkettim.

Bu 'endl' kullanan versiyon:

Alıntı:

>

$ time ./sayiyaz

real 0m4.699s
user 0m0.552s
sys 0m4.144s

Bu da '\n' kullanan versiyon:

Alıntı:

>

$ time ./sayiyaz

real 0m0.241s
user 0m0.212s
sys 0m0.024s

Bir kaç kere çalıştırıldığında sonuçlar çok az farkedilebiliyor ama gene de hemen hemen 4 saniyelik bir fark oluşuyor.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 23, 2011

Hayır, dosya her flush için açılmaz. Karakterler önce bir ara belleğe yazılırlar ve sonra belirli zamanlarda hep birden flush ile yazılırlar.

Konuyu D'ye bağlamış olmak için: writeln da bir ara bellek kullanır (veya kullanabilir?). D'de flush std.stdio.File'ın bir üye işlevidir. Örneğin stdio.flush;

Bu iş aslında o kadar temiz değil, dosyayla aramızda bir de dosya sistemi var. Onun da bu konuda etkileri oluyor sanıyorum.

Ek olarak, C++'ta cout cin'e bağlı olduğu için cin'den okumaya kalkınca da otomatik olarak cout flush edilir. (D'de de olmalı. (?))

Yazdığın program bunu denemek için uygun. Daha çok karakter fazla karakterli çok daha fazla satır yazdırırsan farkını görebilirsin herhalde. (Şimdi zamanım yok; deneyemedim. :))

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 23, 2011

Ben bunu aşağıdaki programla denedim. flush satırının hiçbir etkisi olmuyor.

import std.stdio;

void main()
{
   auto dosya = File("deneme_dosyasi", "w");

   foreach (i; 0 .. 100_000) {
       dosya.writeln(i);
       // dosya.flush();
   }
}

File.flush, C kütüphanesindeki fflush'ı çağırıyormuş. Onun belgesinde de diske yazılacağının garanti edilmediğini söylüyor. Çünkü fflush yazdığını düşünse bile çekirdek kendi ara belleğinde tutuyor olabilirmiş. Onu da yazdırmak için ayrıca fsync ve sync işlevleri var; ama onları D'nin C ilintileri arasında göremedim ve o noktada ilgimi kaybetmeye başladım. :)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 23, 2011

Bu gibi konular gerçekten ihtiyaç duyulana kadar önemli değil. Yazdırmak istiyorsak writeln() demeliyiz ve bitmeli. :)

Daha çok deneyler yapılması gerekir ama gösterdiğin sonuçlara baktığımızda 4 saniyelik fark değil, 4.699/0.241=19.498, yani 19 kat hız farkı olduğu görülüyor. Sisteme çok bağlı bir işlem olduğu için de sistem zamanı 4.144/0.024=172.667, yani 170 kat! ;)

Tek deneye güvenemeyiz tabii ama böyle bir karşılaştırma daha gerçekçi olur.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]