2011-02-09 2 views
0

CSV 파일을 빠르고 효율적으로 코딩 할 수있는 방법이 있습니까? [여기에 주목해야 할 점은 : 백만 줄이있는 CSV 파일에 대해 이야기하고 있습니다]런타임 크리티컬, C 언어로 된 CSV 파일의 읽기 작업

여기서 런타임은 중요한 측정 항목입니다.

인터넷에서 한 자원은 이진 파일 작업을 사용하여 일괄 적으로 읽는 데 집중되어 있습니다. CSV 파일을 읽는 데 도움이된다면 확실합니다.

로버트 갬블 (Robert Gamble)이 SourceForge 코드를 작성한 것처럼 다른 방법도 있습니다. 거기에 네이티브 함수를 사용하여 작성하는 방법이 있습니까?

편집 :

  1. C에서 파일을 읽을 수있는 효율적인 (실행 시간 중요) 방법이 있나요 : 명확하고 더 나은 방법으로 전체 질문을 나눌 수 있습니다? (이 경우 백만 줄의 .csv 파일)

  2. csv 파일을 신속하고 효율적으로 구문 분석 할 수 있습니까?

+0

성능 향상을 위해 어셈블리를 사용할 수 있습니까? – Soham

답변

1

항상 가장 빠른 유형의 파일을 읽고 구문 분석하는 단일 방법은 없습니다. 그러나 CSV에 대해 Ragel 문법을 작성하는 것이 좋습니다. 그것들은 꽤 빠른 경향이 있습니다. 특정 유형의 CSV (쉼표로 구분, ; - 분리, 숫자 만 등)에 맞게 조정할 수 있으며 사용하지 않을 데이터는 건너 뛸 수 있습니다. 필자는 입력 (데이터베이스 덤프)의 대부분을 건너 뛸 수있는 데이터 집합 별 SQL 구문 분석기에 대해 좋은 경험을했습니다.

일괄 읽기가 좋은 생각 일 수 있지만 실제 데이터가 실제로는 stdio- 버퍼링보다 빠르지 만 측정해야합니다. 바이너리 I/O를 사용하면 Windows에서 다소 속도가 빨라지지만 다른 곳에서는 개행을 처리해야합니다.

+0

Ragel은 매우 흥미롭게 보입니다. 나는이 특별한 시간을 사용할 수 없다고 생각한다. (코드가 기계가 아닌 다른 곳에서 실행되기 때문에, ragel을 설치하는 것이 필요할 수도 있기 때문이다.) 나는 아직 라겔에게 완전한 떡방울을 주진 않았지만, 분명히 흥미로웠다. 같은 것을 성취 할 다른 방법이 있습니까? – Soham

+0

@Soham : 개발 기계에 Ragel 만 설치하면됩니다. 더 이상의 의존성없이 C 코드로 컴파일됩니다. Lex/Yacc는 동일한 기능을 제공합니다. –

1

내 경험상 CSV 파일의 구문 분석은 더 높은 수준의 인터프리터 언어에서도 대개 병목 현상이 아닙니다. 보통 대용량의 데이터는 많은 공간을 차지합니다. CSV 파일이 크고 로딩 시간의 대부분은 I/O입니다. 즉 하드 드라이브은 메모리에있는 숫자를 읽습니다.

내 조언은 CSV 압축을 고려하는 것입니다. gzip은 매우 효율적으로 작동하므로 CSV 스트림을 스쿼시 및 복원하여 파일 크기와 I/O 시간을 대폭 줄여 저장 및로드 속도를 높입니다.

Unix에서 개발중인 경우 CSV 입력 및 출력을 gzip -cgunzip -c으로 파이핑 할 때 도움이되는 추가 코드가 없어도이 방법을 사용할 수 있습니다. 그냥 시도해보세요. 저에게 그것은 수십 번이나 일어났습니다.

+0

예, 내 질문에 잘못을 저질렀습니다. 해석은 I/O만큼 큰 병목 현상이 아닙니다. gzip이 더 빠른 I/O를 달성하는 데 사용되는 샘플 코드가 있습니까? – Soham

+0

거대한 CSV를 출력하는 가상의'test.c '로 시작하여'test'로 컴파일하고 압축 여부에 상관없이 속도를 측정 할 수 있습니다 :'time test | gzip -c> test.csv.gz','time test> test.csv'를 입력하십시오. Unix를 사용하지 않는다면 gzip 처리 코드를 검색하고 통합해야합니다. – ulidtko

0

setvbuf을 사용하여 입력 버퍼를 기본값보다 훨씬 더 크게 설정하십시오. 이것은 읽기 속도를 높이기 위해 C에서 할 수있는 유일한 방법입니다. 또한 버퍼 크기를 늘릴 필요가없는 점을 감안할 때 몇 가지 타이밍 테스트를 수행하십시오.

C 외부에서는 .CSV를 SSD 드라이브에 넣거나 압축 된 파일 시스템에 저장할 수 있습니다.

0

큰 텍스트 블록을 메모리 (또는 "메모리 맵"파일)로 가져 와서 메모리의 텍스트를 처리하는 것이 가장 좋습니다.

효율성면에서 볼 때 텍스트 줄은 가변 길이 레코드입니다. 일반적으로, 종결 자의 끝 문자 종결자가 발견 될 때까지 텍스트를 읽습니다. 일반적으로 이것은 문자를 읽고 eol을 확인하는 것을 의미합니다. 많은 플랫폼과 라이브러리는 데이터 블록을 읽고 데이터를 검색하여 eol을 사용하면 더 효율적으로 만들 수 있습니다.

CSV 형식으로 인해 문제가 더욱 복잡해집니다. CSV 파일에서 필드 인은 가변 길이 레코드입니다. 다시 말하지만 쉼표, 탭 또는 세로 막대와 같은 터미널 문자를 검색하십시오.

성능을 향상 시키려면 데이터 레이아웃을 고정 필드 길이와 고정 레코드 길이로 변경해야합니다. 필요한 경우 입력란을 채 웁니다. 응용 프로그램은 여분의 패딩을 제거 할 수 있습니다. 고정 길이 레코드는 읽기와 관련하여 매우 효율적입니다. N 바이트 수를 읽으십시오. 스캔하지 않고 버퍼 어딘가에 덤프하면됩니다.

고정 길이 필드를 사용하면 레코드 (또는 텍스트 줄)에 임의로 액세스 할 수 있습니다. 필드에 대한 색인은 일정하며 쉽게 계산할 수 있습니다. 검색 필요 없음.

요약하면 가변 길이 레코드와 필드는 본질적으로 가장 효율적인 데이터 구조가 아닙니다. 터미널 문자를 검색하는 데 시간이 낭비됩니다. 고정 길이 레코드와 고정 길이 필드는 검색 할 필요가 없으므로보다 효율적입니다.

응용 프로그램이 데이터 집약적 인 경우 데이터를 재구성하면 프로그램의 효율성이 향상 될 수 있습니다.

+0

내가 중요하지 않을 수도 있다는 것을 깨달았 기 때문에 나는 그 구성에 대해 언급하지 않았다. 그러나 명료 함을 위해서, 그것의 10million 행 x 두 배의 6 열을 가정한다. 이 방법으로 선 길이가 일정하다고 가정하는 것이 가능합니까? – Soham