Domanda

Ogni volta che viene importato un file Python che contiene una grande quantità di espressioni regolari statiche, i cicli della CPU vengono spesi per compilare le stringhe nelle loro macchine a stati rappresentative in memoria.

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

Domanda:È possibile memorizzare queste espressioni regolari in una cache su disco in modo precompilato per evitare di dover eseguire le compilazioni regex su ogni importazione?

Il decapaggio dell'oggetto fa semplicemente quanto segue, provocando comunque la compilazione:

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

E re gli oggetti non possono essere sottoposti a marshalling:

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

Soluzione

È possibile memorizzare queste espressioni regolari in una cache su disco in modo precompilato per evitare di dover eseguire le compilazioni regex su ogni importazione?

Non facilmente.Dovresti scrivere un serializzatore personalizzato che si agganci al C sre implementazione del motore regex Python.Eventuali vantaggi in termini di prestazioni sarebbero ampiamente controbilanciati dal tempo e dallo sforzo richiesti.

Innanzitutto, hai effettivamente profilato il codice?Dubito che la compilazione di espressioni regolari sia una parte significativa del tempo di esecuzione dell'applicazione.Ricordare che vengono compilati solo la prima volta che il modulo viene importato nell'esecuzione corrente, successivamente il modulo e i suoi attributi vengono memorizzati nella cache.

Se hai un programma che sostanzialmente si genera una volta, compila una serie di espressioni regolari e poi esce, potresti provare a riprogettarlo per eseguire più test in un'unica invocazione.Quindi potresti riutilizzare le espressioni regolari, come sopra.

Infine, potresti compilare le espressioni regolari in macchine a stati basate su C e quindi collegarle con un modulo di estensione.Anche se questo sarebbe probabilmente più difficile da mantenere, eliminerebbe completamente la compilazione di espressioni regolari dall'applicazione.

Altri suggerimenti

Tieni presente che ogni modulo si inizializza solo una volta durante la vita di un'app, indipendentemente da quante volte la importi.Quindi, se compili le tue espressioni nell'ambito globale del modulo (es.non in una funzione) dovresti stare bene.

Prima di tutto, questa è una chiara limitazione nel modulo Python Re.Causa un limite alla quantità e alla dimensione ragionevole delle espressioni regolari.Il limite è maggiore con processi a lunga esecuzione e minore con processi di breve durata come le applicazioni a riga di comando.

Alcuni anni fa l'ho guardato ed è possibile estrarre il risultato della compilazione, metterlo in salamoia, poi scompattarlo e riutilizzarlo.Il problema è che richiede l'utilizzo degli interni sre.py e quindi probabilmente non funzionerà in diverse versioni di Python.

Mi piacerebbe avere questo tipo di funzionalità nella mia cassetta degli attrezzi.Vorrei anche sapere se esistono moduli separati che potrebbero essere utilizzati in sostituzione.

IL accantonare il modulo sembra funzionare bene:


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()

Puoi quindi creare una bella classe wrapper che gestisca automaticamente la memorizzazione nella cache in modo che diventi trasparente per l'utente...un esercizio lasciato al lettore.

Apri /usr/lib/python2.5/re.py e cerca "def _compile".Troverai il meccanismo di cache interno di re.py.

È possibile posizionare ciascuna regex (o gruppo di regex) in un file separato e quindi importare dinamicamente il file di cui hai bisogno utilizzando il modulo imp.Dubito che si ridimensioni molto bene, ma potrebbe essere ciò di cui hai bisogno.

Ronzio,

Non accantonare l'uso dei sottaceti?

Comunque sono d'accordo con le risposte precedenti.Poiché un modulo viene elaborato solo una volta, dubito che la compilazione di espressioni regolari costituirà il collo di bottiglia dell'app.E il modulo Python re è incredibilmente veloce poiché è codificato in C :-)

Ma la buona notizia è che Python ha una bella comunità, quindi sono sicuro che puoi trovare qualcuno che attualmente hackera proprio ciò di cui hai bisogno.

Ho cercato su Google 5 secondi e ho trovato: http://home.gna.org/oomadness/en/cerealizer/index.html.

Non so se funzionerà, ma in caso contrario, buona fortuna per le tue ricerche :-)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top