1 / 4
Feb 2017

Czesto mamy w zadaniach mocny spam nowych linii. Bufor stdout o ile sie orientuję działa troche tak, że jak mamy nowa linię to zachowuje się trochę jak fflush( stdout );

Przykład z życia wzięty.
Ostatnio zmagałem się z zadaniem wiosno. Po orzymaniu przekroczenia limitu czasu pomyślałem o innym sposobie rozwiązania zadania. uzyskałem 0.03.

Myślę sobie no fajnie ale jakbym miał 0.2 to bym miał 2 strone najlepszych chociaż.

Jestem leniwy więc postanowiłem sprawdzić pewną rzecz o której już jakiś czas myślałem ale jakoś nigdy nie zrealizowałem.

na początku mojego programu umieściłem te dwie linijki.

char buff[8192];
setvbuf( stdout, buff, _IOFBF, sizeof(buff) );

Ta da. 0.02 wyciągnięte. Może miałem farta bo w sumie nie testowałem to z innymi zadaniami ale pewnie za jakiś czas sprawdze kilka. :wink:

Sprawdziłem z 5 zadań. Wszystkie czasy mi te linijki zmniejszyły. pare razy udało mi się dzięki temu zgarnąc 1 stronę. :wink:

  • created

    Feb '17
  • last reply

    Feb '17
  • 3

    replies

  • 1.3k

    views

  • 3

    users

  • 2

    likes

21 days later

Warto by jeszcze napisać co w zasadzie robią te 2 magiczne linijki. Funkcja setvbuf ustawia bufor dla operacji wejścia/wyjścia na pliku przekazanym jako pierwszy parametr (w tym wypadku stdout czyli standardowe wyjście). Drugi parametr określa tablicę znaków, która będzie naszym buforem, zaś czwarty parametr jej rozmiar. Jeżeli w drugim parametrze przekażemy NULL funkcja sama zarezerwuje pamięć na bufor o podanym rozmiarze. Trzeci parametr określa tryb w jakim działa nasz bufor. Stała _IOFBF określa, że dane z bufora będą wypisywane dopiero po jego całkowitym zapełnieniu i właśnie na tym polega nasze przyspieszenie, im większy bufor zarezerwujemy tym mniej wywołań zapisu do pliku będziemy potrzebowali. Należy jednak pamiętać, że to na złożoności algorytmu powinno nam zależeć, a takie przyspieszenia należy traktować bardziej w kategoriach ciekawostki :wink:

Z takim czasem, załapałbyś się co najwyżej na 6 stronę. :wink: A więc czy można wierzyć w twoje porady, gdy odnosi się wrażenie, że jesteś mało dokładny [a więc i wiarygodny?] i nie bardzo wiesz o czym piszesz [może to ja nie wiem?]

Ja spam nowych linii widzę nie tylko w zadaniach, na forum widzę go jeszce częściej, chyba, że znowu nie wiem, o co Ci chodzi :wink:

Więc może najpierw dokładniej zorientuj się? A potem udzielaj rad. Zobacz przynajmniej czym różnią się:
_IOFBF od _IOLBF i ewentualnie od _IONBF
jako jeden z parametrów setvbuf, a warto też abyś podał domyślną wielkość bufora, czy zależy od konkretnego systemu [konfiguracja i rodzaj systemu operacyjnego] lub ustawień [domyślnych] kompilatora itd.

Ja bez takich twoich cudów niewidów, parę razy miałem zmianę czasu o 0.04, ale czy było to dokładnie 5 zadań, czy więcej - nie prowadziłem takich statystyk i raczej bardzo sporadycznie korzystam z tej metody, więc nie będę jej tu opisywał.
Gwarancją zajęcia "stabilnej" pozycji, jest uzyskanie czasu 0.00, i właśnie to zrobiłem w Wiosno!, ale nie za pomocą twoich cudów niewidów, tylko korzystając z "normalnego" fast i/o.

PS
Mimo, że jestem autorem Wiosno!... nie wykorzystałem w moim kodzie [wzorcowym? :wink:] pewnych możliwości optymalizacji, które przyszły mi właśnie do głowy, ale może kiedyś, .... na wiosnę, ... to zrobię i ewentualnie tu opiszę?.

Oczywiście chodziło o 0.02. :wink:

Nie masakrować. Porada jest dobra dla zadań gdzie jest naprawdę dużo testów i odpowiedzi to pojedyńczy int + nowa linia.

Intencje dobre. Chociaz valgrind raz mi się coś skarżył lekko na te dwie linijki więc zalecam ostrożność. Trzeba by dobrze doczytać manual!

Suggested Topics

Want to read more? Browse other topics in Tutoriale, poradniki or view latest topics.