Jak to z tym jest jedni mówią że szybsze jest scanf inni że cin. CO W KOŃCU JEST SZYBSZE?
nie ma roznicy, ktore szybsze.. istotne jest na poczatku co chce sie osiagnac?!
jesli chcesz wprowadzac dane sformatowane, to uzywasz scana, jesli nie i szkoda Ci czasu na wpisywnanie dluzszego ciagu znakuw uzywasz cin, co nie oznacze ze nie jest on uzyteczny..
ja myślę, że to scanf to jest tylko dla pascalowców aby był jakiś odpowiednik :)
w jednej książce helionu jako dodatek to piszą, tylko nie pamiętam w której :(
przeglądałem spisy treści książek o C++.
A ja wczoraj z <ort>bulem </ort>stwierdziłem że szybszy jest scanf :( wysłałem zadanko na oi 10 razy i ciągle było za wolne nie wiedziałem dlaczego a później sprawdziłem jak działa z scanf i było duuuuuuuużo szybciej. POLECAM SCANF JAK KOMUŚ ZALEŻY NA PRĘDKOŚCI.
// to przecież logiczne - procedury są szybsze od metod - ŁF
// jeszcze szybsze jest gets() - w ogóle nie formatuje [mf]
// gets() jest be, fgets() jest lepsze :P - D
szybkość scanf nie powinna nikogo dziwić to jest funkcja, która tylko skanuje znak, a cin to obiekt, który ma często mase nieprzydatnych funkcji... i musi rozpoznawać do jakiej zmienej wczytać dane, a scanf ma to podane...
Jak to z tym jest jedni mówią że szybsze jest scanf inni że cin. CO W KOŃCU JEST SZYBSZE?
Zróbmy więc test:
//
// Speed Kills
// by marcinEc
//
#include <iostream>
#include <cstdio>
#include <fstream>
#include <ctime>
using namespace std;
const int M = 3000;
void pp()
{
int i = 11;
float f = 12.5;
ofstream ff("test.txt");
for (int ii=0; ii<2*M; ii++)
ff << i << ' ' << f << ' ';
}
void stdio_speed()
{
int i;
float f;
clock_t start, end;
double cpu_time_used;
start = clock();
//
for (int ii=0; ii<M; ii++)
scanf("%d %f", &i, &f);
//
end = clock();
cout << "Czas stdio: " << end-start << endl;
}
void iostream_speed()
{
int i;
float f;
clock_t start, end;
double cpu_time_used;
start = clock();
//
for (int ii=0; ii<M; ii++)
cin >> i >> f;
//
end = clock();
cout << "Czas iostream: " << end-start << endl;
}
int main()
{
iostream_speed();
stdio_speed();
stdio_speed();
iostream_speed();
}
U mnie jest:
Czas iostream: 150
Czas stdio: 20
Nie chce tu zaczynać żadnego porównywania, więc nie dawajcie "swoich" wyników tylko się nad tym zastanówcie...
Za to strumienia mają inne zalety :)
// to przecież logiczne - procedury są szybsze od metod - ŁF
Bzdura! Przecież to jest to samo dla zwykłych metod (a inline jeszcze hmmm szybsze...).
szybkość scanf nie powinna nikogo dziwić to jest funkcja, która tylko skanuje znak, a cin to obiekt, który ma często mase nieprzydatnych funkcji... i musi rozpoznawać do jakiej zmienej wczytać dane, a scanf ma to podane...
Jeszcze większe bzdury!
scanf() nie skanuje znaku tylko wczytuje sformatowane wejście z stdin, musi przeparsować łańcuch formatujący i dokonać odpowiednich konwersji string->typ.
cin jest strumieniem istream, który jest wzorcem strumienia, a to oznacza takie bajery jak zgodność typów w wywolaniu operatora << (a scanf() może dostać floata zamiast inta, i co - dupa błąd), a w zasadzie wszystkie metody ma inline na dodatek.
Może warto się chwilę zastanowić, a nie snuć własne teorie? :-|
scanf jest znacznie szybszy i posiada o wiele wieksze mozliwosci formatowania niz strumienie tak wiec zadko kiedy lepiej jest uzyc cin/cout zamiast scanf/printf - dowody: wystarczy poczytac zrodla oprogramowania unixowego z dowolnego systemu (linux/freebsd) itp :P
scanf jest znacznie szybszy i posiada o wiele wieksze mozliwosci formatowania niz strumienie tak wiec zadko kiedy lepiej jest uzyc cin/cout zamiast scanf/printf - dowody: wystarczy poczytac zrodla oprogramowania unixowego z dowolnego systemu (linux/freebsd) itp :P
Chyba trochę nie trafiasz z "argumentami", większe możliwości czego? Chyba z byka spadłeś...
A w drugim przypadku nie masz na uwadze mnóstwa czynników, dla których autorzy wybrali C, a nie C++ :P
Tylko marcinEc, zauważ, że obracasz się tutaj w zakresie jednego programu w C++.
Ja to testowałem na żywym systemie 3 różne programy (dla cin w C++, dla reszty C).
Wyniki (wywołanie time nazw_programu < test.txt, test.txt to duży plik składający się z 111 linii o długości 100 znaków każda)
ge: 3,38 real 2,01 user 0,01 sys
sc: 5,90 real 3,33 user 0,00 sys
ci: 8,96 real 4,79 user 0,02 sys
ge:
#include <stdio.h>
int
main()
{
char tab[500];
long int i;
for(i = 0; i < 0xffffff; i++) {
fgets(tab, 500, stdin);
}
printf("%s\n", tab);
exit(0);
}
sc:
int
main()
{
char tab[500];
long int i;
for(i = 0; i < 0xffffff; i++) {
scanf("%s", tab);
}
printf("%s\n", tab);
exit(0);
}
ci:
#include <iostream>
#include <string>
using namespace std;
int
main()
{
char tab[500];
long int i;
for(i = 0; i < 0xffffff; i++) {
cin >> tab;
}
printf("%s\n", tab);
exit(0);
}
I nie pytajcie mnie dlaczego takie są a nie inne. Mnie nie obchodzi teoria. Praktyka jest taka, jaką przedstawiłem. Przynajmniej tak jest na FreeBSD 5.3 używając gcc 3.4.2
Tak, scanf jest szybszy w praktyce. Jednak najszybszy jest read/fread, bo to po prostu wczytuje bufor i nie analizuje danych jak scanf czy cin czy fgets.
Argumentacja, ze cin.operator << musi byc wolniejszy niz scanf bo to metoda, czy ze musi "rozpoznawac zmienna docelowa" jest oczywiscie bzdurna. Raczej implementacja cin jest skwaszona lub robi cos dodatkowo (obsluga wyjatkow?).
Tak, scanf jest szybszy w praktyce. Jednak najszybszy jest read/fread, bo to po prostu wczytuje bufor i nie analizuje danych jak scanf czy cin czy fgets.
Nom... szybsze jest już chyba tylko bezpośrednie wywołanie funkcji systemowej read, bo wtedy w ogóle pomija się jakiekolwiek sprawdzanie :P
Ja przyjąłem, że tutaj ktoś chce wczytać całą linię, dlatego fread odpadło. Jeżeli chodzi o formatowanie dowolnych danych, to i fgets odpada.
Co do tego, że to metoda... Z punktu widzenia asemblera, to jedno dodatkowe niebezpośrednie odwołanie jest niczym. Nawet, gdyby tam było 10 razy wywoływane przez call, to i tak nie byłoby takich opóźnień. Też stawiałbym na sprawdzanie danych...
scanf jest znacznie szybszy i posiada o wiele wieksze mozliwosci formatowania niz strumienie tak wiec zadko kiedy lepiej jest uzyc cin/cout zamiast scanf/printf - dowody: wystarczy poczytac zrodla oprogramowania unixowego z dowolnego systemu (linux/freebsd) itp :P
Chyba trochę nie trafiasz z "argumentami", większe możliwości czego? Chyba z byka spadłeś...
A w drugim przypadku nie masz na uwadze mnóstwa czynników, dla których autorzy wybrali C, a nie C++ :P
nie wszystko co pisze w ksiazkach jest zgodne z rzeczywistoscia :P
porownaj se ilosc kodu jaka musialbys napisac w c i c++ do prostego przeparsowania danych wejsciowych uzywajac tylko scanf i cin :P
ogółem staram się używać scanf i printf bo program zamiast 80k zajmuje 3K :>
czasami jednak trzeba użyć cin i cout, mówię np. o klasach szablonowych ;P
Nie przesadziles przypadkiem z tym 80k? Moze masz jakas lipna implementacje STLa? U mnie zajmuje ok. 15k. Zreszta do diabla... jakie to ma znaczenie. Komputery maja po 2 GB RAMu a my tu sie nad pojedynczymi kB uzalamy. Nawet komorki za zlotowke maja juz ponad 2MB RAMu.
Ja nie uzywam cin i cout nie dlatego, ze jest wolniejsze (bo jest), czy daje wiekszy kod wynikowy, tylko dlatego ze po prostu nic nie wnosi ponad scanf/printf. A na dodatek niektore implementacje STL maja zwalone srozne dodatki takie jak stringstream, wiec to tez sie raczej nie przydaje. "printf" jest o wiele wygodniejsze od cout. A co do scanfa... No coz, tez za wygodny nie jest, a bezpieczny to juz w ogole. Wole wlasna Javo-podobna implementacje strumieni (wypuszcze ja wraz z reszta bajerow w okolicach lutego/marca - bedzie opensource).
Nie przesadziles przypadkiem z tym 80k? Moze masz jakas lipna implementacje STLa? U mnie zajmuje ok. 15k.
Hmmm u mnie 80k na devie to najmniej :| W Mingwstudio kod wynikowy zajmuje ponad 200k(!) z nagłówkiem iostream i jednym cinem 8-|
Zreszta do diabla... jakie to ma znaczenie. Komputery maja po 2 GB RAMu a my tu sie nad pojedynczymi kB uzalamy.
No tak, ale to zastanawiające czemu taki printf może zajmować kilkaset bajtów, a cout kilkadziesiąt kb. poza tym ma to ogromne znaczenie w DOSie.
iostream to jest caly zestaw klas. Nawet jesli wielu rzeczy nie uzywasz, to wiele metod jest dolacznych przy linkowaniu statycznym i stad masz taki duzy kod. Uzyj linkowania dynamicznego z stdlib (u mnie jest taki domyslny - widocznie pod MinGW nie) i bedziesz miec maly kod. Zgadzam sie, ze iostream jest niepotrzebnie przerosniety, a mimo to malo elastyczny...
hmm à propos tematu takie male btw: oplaca sie robic wlasna klase strumieni ktora by swoja struktura przypominala stl ale oprzec ja na C i dodac formatowanie ?
Nie przesadziles przypadkiem z tym 80k? Moze masz jakas lipna implementacje STLa? U mnie zajmuje ok. 15k. Zreszta do diabla... jakie to ma znaczenie. Komputery maja po 2 GB RAMu a my tu sie nad pojedynczymi kB uzalamy. Nawet komorki za zlotowke maja juz ponad 2MB RAMu.
Ale pamięć podręczna jest mała. A im więcej da się zmieścić tam, tym szybciej program chodzi :P
Ale to już takie małe zboczenie asemblerowe :P
Mialem na mysli - jakie ma znaczenie, ze w KODZIE WYNIKOWYM znajdzie sie kilkadziesiat kilo dodatkowego balastu, bo o tym rozmawialismy. Zauwaz, ze nawet jesli w kodzie wynikowym bedziesz miec 80% kodu nieuzywanego, to te nieuzywane strony nie beda zapychaly pamieci podrecznej, ba nie musza nawet zapychac normalnej pamieci. Wiec program ze zbednym kodem tylko zaladuje sie nieco wolniej (no coz - z dysku odczytac na ogol trzeba), ale dzialac bedzie tak samo szybko. W najgorszym przypadku nieuzywane strony wyladuja na swapie. Oczywiscie to jest tylko uproszczenie teoretyczne - w praktyce pewien wplyw oczywiscie bedzie to miec, bo czasem jakis kawalek tego nieuzywanego kodu bedzie zapewne wykonany (zasada 20/80).
Lepiej zwracac uwage na to ile naprawde RAMu program potrzebuje w czasie wykonania (zarowno kod jak i DANE, w tym te dynamicznie alokowane), niz sugerowac sie wielkoscia execa. Nie zawsze program o execu 1MB bedzie chodzil wolniej w wyniku strat na nietrafianiu w pamiec podreczna niz program o execu 250 kB.
Mialem na mysli - jakie ma znaczenie, ze w KODZIE WYNIKOWYM znajdzie sie kilkadziesiat kilo dodatkowego balastu, bo o tym rozmawialismy.
Ależ oczywiście. To co na dysku, to nie ma już prawie żadnego znaczenia... Prawie, bo mi się przypomina jak jakiś konkurs, chyba dla szkół średnich i gimnazjów, wygrał gostek, co napisał program, pojedynczego exeka o wielkości ponad 50MB. Podziwiam go... Co on tam upchał? Film?
Ale to są oczywiście skrajne przypadki.
[Wątek się trochę zrobił trollingowy, ale...Już nawet na pamięc masową zszedł.. Czekam na strumienie na MMX i implementację na jakiś procesor RISC :D ]
nie wszystko co pisze w ksiazkach jest zgodne z rzeczywistoscia :P
porownaj se ilosc kodu jaka musialbys napisac w c i c++ do prostego przeparsowania danych wejsciowych uzywajac tylko scanf i cin :P
Nie wiem o co Ci chodzi...? W jakich książkach...?!
Proszę bardzo:
int i;
int ii = scanf("%d", &i);
if (ii!=1 || ii==EOF) {//error or eof}
else {}
int i;
if ( !(cin >> i) ) {//error}
else {}
Gdzie się mniej napisałem? A teraz zmien 'i' na float i gdzie się więcej napisze ZNOWU?! [diabel]
Wątek był na temat prędkości scanf() vs cin. scanf() JEST szybsze za cenę: błędów formatowania, exploitingu (bufory, %n :) ), braku jakiegokolwiek obiektowego podejścia do strumienia (no bo to C), itd.
Co wy ludzie jakieś własne teorie dorabiacie do tego?!
zacznij pisac prawdziwy parser przy uzyciu strumieni,.. z gory gratuluje ambicji :P
ale fakt strumienie sa wygodne i przyznaje ze czasem ich uzywam choc z reguly znacznie lepiej pracuje mi sie w ansi-c
co do tematu watka to formatowanie w C jest szybsze niz w C++ i jest fakt, choc przydatny tylko gdy trzeba wykonac tysiace takich operacji a nie wywalic komunikat na ekran...
// ehh, koniec tego dobrego, niech kazdy używa tego co mu pasuje [mf]
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.