C malloc/free + fgets 성능
-
13-09-2019 - |
문제
파일 A의 선을 통해 루프 할 때 선을 구문 분석하고 각 문자열을 넣습니다.char*
) a char**
.
라인 끝에서 나는 파일 B를 열고 사용하는 절차를 실행합니다. fgets
, fseek
그리고 fgetc
해당 파일에서 문자를 가져옵니다. 그런 다음 파일 B를 닫습니다.
각 라인에 대해 파일 B를 다시 열고 재 클레싱합니다.
내가 알고 싶은 것은 다음과 같습니다.
사용으로 인한 상당한 성능이 있습니까?
malloc
그리고free
, 나는 정적 인 것을 사용해야합니다myArray[NUM_STRINGS][MAX_STRING_WIDTH]
역학 대신char** myArray
?파일 B를 열고 닫음으로써 상당한 성능 오버 헤드가 있습니까 (개념적으로 수천 번)? 내 파일 a가 정렬 된 경우, 내가 사용할 방법이 있습니까?
fseek
파일 B에서 "뒤로"이동하려면 이전에 파일 B에있는 위치를 재설정하려면?
편집하다 두 가지 접근 방식이 런타임을 크게 줄였습니다.
내 파일 B는 실제로 24 파일 중 하나입니다. 동일한 파일 B1을 천 번, B2를 천 번 열기를하는 대신 파일 B1을 한 번 열고 B2를 한 번 닫습니다.
fopen
그리고fclose
대략 24로 운영.나는 사용했다
rewind()
파일 포인터를 재설정합니다.
이로 인해 대략 60 배 속도 향상이 발생했으며, 이는 충분한 것 이상입니다. 나를 가리려고 주셔서 감사합니다 rewind()
.
해결책
동적 배열이 제 시간에 커지면 일부에 대한 사본 비용이 있습니다. realloc
에스. "항상 이중"휴리스틱을 사용하는 경우, 이것은 O (n)으로 상각되므로 끔찍하지 않습니다. 미리 크기를 알고 있다면 스택 할당 배열이 여전히 더 빠릅니다.
두 번째 질문에 대해 읽으십시오 rewind
. 항상 열고 닫는 것보다 빠르며 리소스 관리를 덜 수행 할 수 있습니다.
다른 팁
내가 알고 싶은 것은 다음과 같습니다.
- 코드가 올바르게 작동합니까?
- 당신의 목적을 위해 충분히 빠르게 진행되고 있습니까?
이 두 가지 대답이 "예"라면 아무것도 바꾸지 마십시오.
개방 및 폐쇄는 다른 프로그램이 해당 리소스와 경쟁하는지에 따라 변수 오버 헤드를 갖습니다.
먼저 파일 크기를 측정하십시오 그런 다음이를 사용하여 배열 크기를 미리 계산하여 하나의 큰 힙 할당을 수행하십시오.
다차원 배열을 바로 얻지는 않지만 약간의 포인터 산술이 있습니다.
다른 파일의 위치 정보를 캐시 할 수없고, 그것을 열고 닫지 않고 이전 Seek 인덱스를 오프셋으로 사용하십시오. 정확한 논리에 따라 다릅니다.
파일이 크면 디스크 I/O는 메모리 관리보다 훨씬 비쌉니다. 프로파일 링 전에 malloc/무료 성능에 대한 걱정은 병목 현상이 조기 최적화임을 나타냅니다.
빈번한 개방/닫기의 오버 헤드가 프로그램에서 중요 할 수 있지만, 파일이 작지 않는 한, 실제 I/O는 더 비싸지 않을 수 있습니다. 여분의 디스크 I/O의 원인. 그리고 네, ftell ()을 사용하여 파일의 현재 위치를 가져오고 fseek가 seek_set을 사용하여 얻을 수 있습니다.
동적 메모리를 사용하면 항상 성능이 히트합니다. 정적 버퍼를 사용하면 속도 부스트가 제공됩니다.
파일을 다시 열면 성능이 올라갈 것입니다. FSEEK (POS, SEEK_SET)를 사용하여 파일 포인터를 파일의 모든 위치로 설정하거나 FSEEK (Offset, Seek_Cur)를 상대적으로 이동할 수 있습니다.
상당한 성능 히트는 상대적이며, 그게 자신에게 어떤 의미가 있는지 결정해야합니다.
필요한 실제 공간을 할당하는 것이 더 낫다고 생각하며 오버 헤드는 중요하지 않을 것입니다. 이것은 공간과 스택 오버플로를 낭비하지 않습니다
예. IO가 캐시되었지만 불필요한 SyScalls (열린 및 닫기)를 만들고 있습니다. 아마도 fseek를 사용하십시오
SEEK_CUR
또는SEEK_SET
.
두 경우 모두 있습니다 약간 성능은 적중이지만 중요성은 파일의 크기와 프로그램이 수행하는 컨텍스트에 따라 다릅니다.
실제로 문자열의 최대 수와 최대 너비를 알고 있다면 훨씬 빠릅니다 (그러나 "최대"보다 적은 것을 사용하면 많은 메모리를 낭비 할 수 있습니다). 행복한 매체는 C ++에서 많은 동적 배열 구현을 수행하는 것입니다. MyArray를 재 할당해야 할 때마다 필요한 것보다 두 배나 많은 공간을 할당하며, 일단 공간이 부족한 후에는 다시 재 할당하십시오. 이것은 O (로그 N) 성능 비용이 있습니다.
이것은 큰 성능이 될 수 있습니다. 세부 사항은 알고리즘에 따라 다르지만 FSEEK를 사용하는 것이 좋습니다.
나는 종종 성능 오버 헤드가 malloc
메모리에있는 저수준 C 핸들러. 이러한 메모리 영역 이이 메모리를 만지는 것보다 상각 시간에 더 큰 시간 동안 정적이고 손길이 닿지 않는 한, 정적 배열을 고수하는 것이 더 유리할 수 있습니다. 결국, 그것은 당신에게 달려 있습니다.