2010-04-27 2 views
8

필자는 우리가 한 강의에서 사용하는 일부 파일 형식 (ARFF)에 대한 직접적인 재귀 순수 파이썬 파서를 작성했습니다. 지금 내 운동 제출을 실행하는 것은 너무 느립니다. 필자의 파서에서 가장 많은 시간을 보냈다. CPU 사용 시간이 많이 걸리며 HD는 병목 현상이 아닙니다.파이썬에서 빠른 파서 작성하기

파이썬에서 파서를 작성하는 데 어떤 뛰어난 방법이 있는지 궁금합니다. 차라리 C로 다시 작성하지 않을 것입니다. 자이 썬을 사용하려고했지만 성능이 많이 떨어졌습니다! 내가 파싱 한 파일은 부분적으로 거대한 (> 150 MB) 매우 긴 줄이 있습니다.

내 현재 구문 분석기는 한 문자 만 미리보기하면됩니다. 나는 여기에 근원을 게시 하겠지만 그것이 좋은 생각인지는 모르겠다. 결국 제출 기한이 아직 끝나지 않았습니다. 그러나이 연습의 초점은 파서가 아닙니다. 사용할 언어를 선택할 수 있으며 이미 Java 용 파서가 있습니다.

참고 : x86_64 시스템을 사용하고 있으므로 psyco (PyPy라고도 함) 옵션이 없습니다.

업데이트 : 이제 파서/작성기를 bitbucket에 업로드했습니다.

+4

파서를 프로파일 링 했습니까? 기회는 모든 것을 담고있는 병목 일뿐입니다. –

+0

코드 예없이 괜찮은 조언을하는 것은 불가능합니다. 하나의 큰 결함이있는 건전한 기술을 사용하거나 전체 접근법을 다시 만들어야 할 수도 있습니다. 우리는 알 방법이 없습니다. – mikerobi

+0

psyco를 사용해 보셨습니까? –

답변

8

ANTLR 또는 pyparsing을 사용하면 구문 분석 속도가 빨라질 수 있습니다.

현재 코드를 유지하려면 Cython/PyPy을보고 성능을 향상시킬 수 있습니다 (최대 4 배까지 가능).

+1

pyparsing을 사용하면 속도가 빨라지 겠지만 병목 현상이 발생하는 위치에 대한 통찰력을 얻을 수 있습니다. 또한 ARFF pserarsing 파서가 이미 작성되었고 어딘가에서 빠져 있다고 생각합니다. – PaulMcG

+0

사실입니다. 파이핑 (pyyparsing)이 PyPy 나 Cython과 어울리는 지 모르겠습니다. – wvd

+0

weka 사이트에서 링크 된 ARFF pyparsing 구문 분석기가 매우 불완전합니다 (그게 당신이 말하는 것이라면). 또한 cython을 사용해 보았습니다. 그러나 yield를 많이 사용했기 때문에 hg 버전을 사용해야했기 때문에 segfaults 코드가 생성되었습니다. – panzi

7

추가 정보없이 가장 일반적인 팁은 전체 파일 또는 적어도 중요한 부분을 한 번에 메모리로 읽는 것입니다. 당신은 한 번에 한 글자를 읽고 여기 저기에서 찾고 싶지 않습니다. 후드에서 진행되는 버퍼링과 상관없이 전체 작업을 메모리에 두는 것이 좋습니다. 따라서 원하는대로 작업 할 수 있습니다.

필자는 파이썬으로 파서를 작성했으며 특별히 다른 언어로 작성된 파서보다 속도가 느리다는 특별한 요구 사항은 없습니다. 이런 종류의 일들이 그렇듯이, 당신이 할 필요가없는 일을하는 것이 더 낫습니다. 아이템의 클래스 중, 같은 오브젝트를 생성하고 파괴하고 다시 생성하는 것은 어딘가에 저장하는 것보다 비용이 많이 든다. 값을 반복해서 다시 계산하는 것은 어딘가에 저장하는 것보다 비용이 많이 듭니다. 등등.

특히 파이썬에서 사람들이 빠지게되는 하나의 함정은 많은 불필요한 문자열 조작을 수행합니다. 한 번에 한 문자 씩 문자열에 추가하지 마십시오. 토큰을 만들 때 "주인공"문자열에 대한 작업을 수행하고 토큰을 하나씩 제거합니다. (즉, "마스터"문자열에 색인을 붙이고 시작 및 종료 지점을 파악한 다음 token = master[start:end]으로 잡습니다.) 한 번에 한 문자 씩 문자열 연결을 수행하면 성능 비참함에 대한 짧은 경로가됩니다. 나는 비록 당신이 원한다면/용의주도하는 이유가 필요하다고 생각합니다. for c in master: newstr += c 당신은 운이 좋으면 목록에 c를 채우고 newstr = ''.join(newstr_charlist)을 얻을 수 있습니다.

+0

나는 이것을 많이 사용한다. 가장 빠른 방법인가? 그러나이 특정 코드는 사용 사례에 의해 트리거되지 않습니다. http://pastebin.com/yAmEcKB8 – panzi

+0

아, 파일에서 4096 바이트의 청크를 읽습니다 (readc() 및 peek() 메서드는 이러한 청크에서 작동합니다). 파일 크기가 150MB를 넘기 때문에 홀 파일을 읽는 것이 좋습니다. – panzi

+2

현대 컴퓨터에는 512M 이상의 메모리가 있습니다. 150MB를 읽는 것은 아무 것도 아닙니다. :) –

관련 문제