Najszybsze pobieranie danych do napotkania EOF

Najszybsze pobieranie danych do napotkania EOF
PR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 64
0

Witam jak mogę najszybciej pobrać liczby całkowite int do momentu napotkania EOF.
Stosuje sposób whlile(!cin.eof()) ale w ten sposób nie mogę osiągnąć odpowiedniego czasu do wykonania zadania które znajduje się na spoju

SI
  • Rejestracja: dni
  • Ostatnio: dni
0

Zajrzyj tutaj http://pl.spoj.com/forum/viewtopic.php?f=10&t=1206&sid=88a155f447ed7020e8ad80ef43ce99db. Generalnie jak potrzebujesz szybko czytać i wypisywać, to stosuj rozwiązania z C. Cin/out są wolniejsze od scan/printf

_13th_Dragon
  • Rejestracja: dni
  • Ostatnio: dni
1

while(scanf("%d",&i)==1) { ... } - ale problem raczej masz w algorytmie.
Jeżeli jednak jest tak jak mówi @Shalom w komentarzach niżej to serię liczb wczytujesz np tak:

Kopiuj
unsigned value=0,len=0;
char ch;
while((ch=getchar())!=EOF)
  {
   if(isdigit(ch))
     {
      ++len;
      value=value*10+ch-'0';
     }
   else if(len)
     {
      printf("%d\n",value);
      ...
      value=len=0;
     }
  }
Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
1

@_13th_Dragon takie czytanie po znaku będzie szybsze? Nie lepiej tu jakiś fread na całe wejście?

_13th_Dragon
  • Rejestracja: dni
  • Ostatnio: dni
0
Shalom napisał(a):

@_13th_Dragon takie czytanie po znaku będzie szybsze? Nie lepiej tu jakiś fread na całe wejście?

Sam sobie odpowiedź: http://stackoverflow.com/questions/8589425/how-does-fread-really-work/8590471#8590471

P.S. getchar() zwraca getc(stdin) przeważnie jest zrealizowany jako makro.

msm
  • Rejestracja: dni
  • Ostatnio: dni
1

http://stackoverflow.com/questions/8589425/how-does-fread-really-work/8590471#8590471

Here is the siimple implementation of fread from Minix

Nie wiem jak w minixie, normalnie wygląda to jednak inaczej.
Jakaś przykładowe inne implementacje (losowe z google): https://www.opensource.apple.com/source/Libc/Libc-167/stdio.subproj/fread.c, http://fxr.watson.org/fxr/source/stdio/fread.c?v=FREEBSD-LIBC, http://plibc.sourceforge.net/doxygen/fread_8c-source.html
Fakt że najwięcej czasu zajmie i tak faktyczny odczyt z dysku (jeśli dane są np. przekierowywane z pliku, bo przy wpisywaniu z klawiatury raczej problemów z wydajnością nie będzie), ale memcpy które siedzi w takim freadzie prawdopodobnie kopiuje dużo szybciej niż po bajcie.

Btw. Rev zwraca uwagę że kompatybilność z POSIX wymaga zachowania się tak samo jak taka pętla:

For each object, size calls shall be made to the fgetc() function and the results stored, in the order read, in an array of unsigned char exactly overlaying the object

RE
  • Rejestracja: dni
  • Ostatnio: dni
1

W glibc podobnie jak u Apple fread prowadzi do memcpy, a nie getc.

RE
  • Rejestracja: dni
  • Ostatnio: dni
3

Nie, fread() prowadzi do __srefill(fp) tak samo jak getchar()

glibc 2.18

fread -> _IO_fread -> _IO_XSGETN -> __xsgetn -> _IO_file_xsgetn -> memcpy oraz _IO_SYSREAD, które na uniksach prowadzi do syscallu read.

PR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 64
0
_13th_Dragon napisał(a):

while(scanf("%d",&i)==1) { ... } - ale problem raczej masz w algorytmie.
Jeżeli jednak jest tak jak mówi @Shalom w komentarzach niżej to serię liczb wczytujesz np tak:

Kopiuj
unsigned value=0,len=0;
char ch;
while((ch=getchar())!=EOF)
  {
   if(isdigit(ch))
     {
      ++len;
      value=value*10+ch-'0';
     }
   else if(len)
     {
      printf("%d\n",value);
      ...
      value=len=0;
     }
  }

Faktycznie działa 2 razy szybciej, ale może mi ktoś wytłumaczyć jak to działa bo nie mogę zrozumieć

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.