El método de búsqueda de texto más rápido en un archivo de texto grande

Estoy haciendo una búsqueda de texto en un archivo txt bastante grande (100k líneas, 7mo) El texto no es tan grande pero necesito muchas búsquedas. Quiero buscar una cadena de destino y devolver la línea donde aparece. Mi archivo de texto está formateado para que el objective solo pueda aparecer en una línea.

¿Cuál es la forma más eficiente? Hago muchas búsquedas por lo que quiero mejorar la velocidad. Aquí está mycode ahora mismo:

def lookup_line(target): #returns line of the target, or None if doesnt exist line=None dir=os.path.dirname(__file__) path=dir+'/file.txt' file=open(path,'r') while line==None: l=file.readline() l=unicode(l,'utf-8') if target in l: break if l=='': break #happens at end of file, then stop loop line=l if line=='':line=None #end of file, nothing has been found file.close() return line 

Utilizo este código de Python para una aplicación de Google Appengine.

¡Gracias!

  1. Carga todo el texto en la memoria RAM a la vez. No lea línea por línea.
  2. Busca el patrón en el blob. Si lo encuentra, use text.count('\n',0,pos) para obtener el número de línea.
  3. Si no necesita el número de línea, busque la EOL anterior y la siguiente para cortar la línea del texto.

El bucle en Python es lento. La búsqueda de cadenas es muy rápida. Si necesitas buscar varias cadenas, usa expresiones regulares.

Si eso no es lo suficientemente rápido, use un progtwig externo como grep .

Si busca el mismo archivo de texto una y otra vez, considere indexar el archivo. Por ejemplo, cree un diccionario que asigne cada palabra a las líneas en las que se encuentra. Esto tomará un tiempo para crear, pero luego hará búsquedas O (1).

Si está buscando diferentes archivos de texto, o no puede indexar el archivo por alguna razón, probablemente no obtendrá más rápido que el algoritmo KMP .

EDITAR: El índice que describí solo funcionará para búsquedas de una sola palabra, no para búsquedas de varias palabras. Si desea buscar varias palabras (cualquier cadena), entonces probablemente no podrá indexarlo.

Primero, no decodifique explícitamente los bytes.

 from io import open 

Segundo, considera cosas como esta.

 with open(path,'r',encoding='UTF-8') as src: found= None for line in src: if len(line) == 0: break #happens at end of file, then stop loop if target in line: found= line break return found 

Esto se puede simplificar ligeramente para usar el return None o la return line lugar de una break . Debería correr un pelo más rápido, pero es un poco más difícil hacer cambios cuando hay varios rendimientos.