Najszybsze pobieranie danych do napotkania EOF

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

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

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:

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;
     }
  }
1

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

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.

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

1

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

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.

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:

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ć

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