scanf vs cin

0

Jak to z tym jest jedni mówią że szybsze jest scanf inni że cin. CO W KOŃCU JEST SZYBSZE?

0

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..

0

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++.

0

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

0

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...

0

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? :-|

0

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

0

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

0

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

0

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?).

0

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...

0

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

0

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

0

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).

0

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.

0

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...

0

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 ?

0

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

0

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.

0

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.

0

[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?!

0

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]

1 użytkowników online, w tym zalogowanych: 0, gości: 1