2008-09-15 5 views
18

대용량의 정적 정규 표현식을 포함하는 파이썬 파일을 가져올 때마다 메모리의 대표적인 상태 머신으로 문자열을 컴파일하는 데 CPU 사이클이 소요됩니다.컴파일 된 정규식 개체를 파이썬으로 캐싱 하시겠습니까?

a = re.compile("a.*b") 
b = re.compile("c.*d") 
... 

질문 : 각 수입에 정규식 컴파일을 실행하는 것을 방지하기 위해 미리 컴파일 된 방식으로 디스크의 캐시에 이러한 정규 표현식을 저장할 수 있습니까?

>>> import pickle 
>>> import re 
>>> x = re.compile(".*") 
>>> pickle.dumps(x) 
"cre\n_compile\np0\n(S'.*'\np1\nI0\ntp2\nRp3\n." 

그리고 re 객체가 unmarshallable은 다음과 같습니다 : 각 모듈의 수명 동안 한 번만 자체를 초기화하는 것이

>>> import marshal 
>>> import re 
>>> x = re.compile(".*") 
>>> marshal.dumps(x) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: unmarshallable object 
+1

슬프게도, 내 응용 프로그램 (900 정규식 및 계산)에도이 문제가 있습니다. 불행히도이 스레드에는 해결책이 없습니다. –

답변

13

각 정규식을 실행할 때마다 정규식 컴파일을 수행 할 필요가 없도록 미리 컴파일 된 방식으로 디스크의 캐시에 이러한 정규식을 저장할 수 있습니까?

쉽지 않음. 파이썬 정규 표현 엔진의 C sre 구현에 연결되는 커스텀 시리얼 라이저를 작성해야합니다. 모든 성능상의 이익은 필요한 시간과 노력으로 크게 능가 할 것입니다.

먼저 코드를 프로파일 링 했습니까? 정규 표현식을 컴파일하는 것이 응용 프로그램의 런타임에서 중요한 부분이 아닌지 의심 스럽습니다. 모듈은 현재 실행에서 모듈을 처음 가져올 때만 컴파일됩니다. 그 후에 모듈과 모듈의 속성이 메모리에 캐시됩니다.

기본적으로 한 번 생성되고 여러 개의 정규식을 컴파일 한 다음 종료 할 경우 한 번의 호출로 여러 번의 테스트를 수행 할 수 있습니다. 그러면 위와 같이 regexes를 다시 사용할 수 있습니다.

마지막으로 정규식을 C 기반 상태 시스템으로 컴파일 한 다음 확장 모듈과 연결할 수 있습니다. 이것은 유지하기가 더 어려울 지 모르지만, 응용 프로그램에서 정규 표현식 편집을 완전히 제거합니다.

2

주 목적은 단순히 다음은, 원인이 컴파일 어쨌든 일이 않는 산세

앱을 몇 번이나 가져 오던간에 따라서 모듈의 전역 범위 (즉, 함수가 아닌)에서 표현식을 컴파일하면 괜찮을 것입니다.

-1

각 정규식 (또는 정규식 그룹)을 별도의 파일에 배치 한 다음 imp 모듈을 사용하여 필요한 파일을 동적으로 가져올 수 있습니다. 나는 그것이 잘 잘랐다는 것을 의심 할 만하다.

+1

정규식은 명시 적으로 또는 암시 적으로 컴파일해야하며이 작업에는 시간이 필요합니다. –

0

shelve 모듈이 잘 작동하도록 나타납니다


import re 
import shelve 
a_pattern = "a.*b" 
b_pattern = "c.*d" 
a = re.compile(a_pattern) 
b = re.compile(b_pattern) 

x = shelve.open('re_cache') 
x[a_pattern] = a 
x[b_pattern] = b 
x.close() 

# ... 
x = shelve.open('re_cache') 
a = x[a_pattern] 
b = x[b_pattern] 
x.close() 

당신은 다음 사용자에게 투명하게되도록 자동으로 당신을위한 캐싱을 처리하는 좋은 래퍼 클래스를 만들 수 있습니다 ... 운동은 왼쪽 독자.

+2

'shelve' 모듈은'pickle'을 내부적으로 사용합니다. 패턴은 여전히 ​​선반에서로드 할 때 다시 컴파일됩니다. –

-1

흠,

사용 피클을 보류하지 않습니다?

어쨌든, 나는 이전 anwsers에 동의합니다. 모듈은 한 번만 처리되기 때문에, 컴파일 정규식은 앱 병목 일 것입니다.그리고 파이썬 모듈은 C :-)로 코딩되어 있기 때문에 사기가 빠르다.

그러나 좋은 소식은 파이썬에는 멋진 커뮤니티가있어서 현재 필요한 사람을 해킹 할 수있는 사람을 찾을 수있을 것이라고 확신한다.

나는 5 초 봤는데 발견 : http://home.gna.org/oomadness/en/cerealizer/index.html. 그것을 할 것입니다 경우

은 몰라 그렇지 않은 경우, 당신의 행운 :-)

0

열기 /usr/lib/python2.5/re.py을 연구하고 "데프 _compile"를 찾습니다. re.py의 내부 캐시 메커니즘을 찾을 수 있습니다.

1

우선, 이것은 python re 모듈에서 명확한 제한 사항입니다. 그것은 얼마나 많은 정규식이 얼마나 합리적인지를 제한하는 원인이됩니다. 제한 시간은 실행중인 프로세스가 길면 커지며 명령 줄 응용 프로그램과 같이 수명이 짧은 프로세스에서는 작아집니다.

몇 년 전에 필자는 그것을 보았고 컴파일 결과를 찾아서 피클 해본 다음 다시 채우고 재사용 할 수있었습니다. 문제는 sre.py 내부를 사용해야하므로 다른 Python 버전에서는 작동하지 않는다는 것입니다.

내 도구 상자에 이런 종류의 기능을 갖고 싶습니다. 대신에 사용할 수있는 별도의 모듈이 있다면 알고 싶습니다.

관련 문제