FGET보다 빠른 입력 라인을 읽으십니까?
-
06-09-2019 - |
문제
저는 성능이 매우 중요하지만 중요하지 않은 프로그램을 작성하고 있습니다. 현재 나는 a.에서 텍스트로 읽고있다 FILE*
라인별로 나는 사용합니다 fgets
각 라인을 얻으려면. 일부 성능 도구를 사용한 후 응용 프로그램이 실행중인 시간의 20 ~ 30%가 내부에 있음을 알았습니다. fgets
.
텍스트 줄을 얻는 더 빠른 방법이 있습니까? 내 응용 프로그램은 여러 스레드를 사용하려는 의도없이 단일 스레드입니다. 입력은 stdin 또는 파일에서 발생할 수 있습니다. 미리 감사드립니다.
해결책
당신은 당신이 어떤 플랫폼에 있는지 말하지 않지만, 그것이 Unix와 비슷하다면, 당신은 read () 시스템 호출을 시도 할 수 있습니다. 이것은 약간의 속도가 약간 상승 할 수 있습니다. 반면에, 그것은 속도를 늦출 수 있습니다. 알아내는 유일한 방법은 그것을 시도하고 보는 것입니다.
다른 팁
fgets_unlocked ()를 사용하지만 먼저 무엇을하는지주의 깊게 읽으십시오.
fgets () 대신 fgetc () 또는 fgetc_unlocked ()로 데이터를 가져옵니다. fgets ()를 사용하면 데이터가 파일에서 내부 버퍼로 C 런타임 라이브러리에 의해 두 번 메모리로 복사 된 다음 (스트림 I/O가 버퍼링 됨), 해당 내부 버퍼에서 프로그램의 배열로 복사됩니다.
한 번에 전체 파일을 읽으십시오. 버퍼로 이동하십시오.
해당 버퍼에서 라인을 처리하십시오.
이것이 가능한 가장 빠른 솔루션입니다.
많은 양의 데이터를 RAM에 읽은 다음 작업을 수행하여 디스크에서 읽는 데 소요되는 시간을 최소화 할 수 있습니다. 디스크에서 읽는 것은 느리기 때문에 전체 파일을 한 번 (이상적으로) 읽음으로써 수행 한 다음 작업을 수행하여 수행하는 시간을 최소화하십시오.
CPU 캐시가 CPU가 실제로 RAM으로 돌아가는 시간을 최소화하는 방식과 마찬가지로 RAM을 사용하여 실제로 디스크로 이동하는 횟수를 최소화 할 수 있습니다.
환경에 따라 SetVbuf ()를 사용하여 파일 스트림에서 사용하는 내부 버퍼의 크기를 늘리면 성능이 향상되지 않을 수 있습니다.
이것은 구문입니다 -
setvbuf (InputFile, NULL, _IOFBF, BUFFER_SIZE);
여기서 inputfile은 fopen ()을 사용하여 방금 열린 파일에 대한 파일*이고 buffer_size는 버퍼의 크기입니다 (이 호출에 의해 할당됨).
다양한 버퍼 크기를 시도하여 긍정적 인 영향이 있는지 확인할 수 있습니다. 이것은 전적으로 선택 사항이며, 런타임은이 호출로 전혀 아무것도하지 않을 수 있습니다.
데이터가 디스크에서 나오면 IO 묶을 수 있습니다.
이 경우 더 빠른 디스크를 얻으십시오 (그러나 먼저 기존 디스크를 최대한 활용하고 있는지 확인하십시오 ... 일부 Linux 배포판은 상자에서 디스크 액세스를 최적화하지 않습니다 ()hdparm
))), 데이터를 메모리에 무대 (RAM 디스크에 복사하여 예정) 미리 준비하거나 대기 할 준비를하십시오.
당신이 IO 묶지 않으면 많은 시간을 복사 할 수 있습니다. 소위 제로 카피 방법의 혜택을 누릴 수 있습니다. 메모리와 같은 것이 파일을 맵핑하고 포인터를 통해서만 액세스합니다.
그것은 내 전문 지식을 넘어서서 약간의 지식이 풍부한 도움을 읽거나 기다려야합니다.
BTW-- 당신은 문제가 가치있는 것보다 더 많은 일을하고있을 것입니다. 어쩌면 더 빠른 기계가 모든 문제를 해결할 것입니다 ...
NB-- 표준 입력을 메모리 매핑 할 수 있다는 것은 분명하지 않습니다 ...
fread ()를 살펴보십시오. 특히 Fread의 버퍼가 65536으로 설정된 경우 훨씬 더 빨리 읽습니다. 단점 : 많은 작업을 수행하고 본질적으로 이진 읽기에서 텍스트로 변환하기 위해 자신의 GetLine 기능을 작성해야합니다. 체크 아웃 : 파일 I/O
OS가 지원하면 비동기 파일 판독 값을 시도 할 수 있습니다. 즉, CPU가 다른 작업을 수행하는 동안 파일을 메모리로 읽습니다. 따라서 코드는 다음과 같습니다.
start asynchronous read
loop:
wait for asynchronous read to complete
if end of file goto exit
start asynchronous read
do stuff with data read from file
goto loop
exit:
둘 이상의 CPU가있는 경우 하나의 CPU가 파일을 읽고 데이터를 라인으로 구문 분석하면 다른 CPU는 각 라인을 가져 와서 처리합니다.