Creando Una Base De Datos. Algo Lento [SOLUCIONADO]


Ir a la página 1, 2  Siguiente

Objetivo: Creando Una Base De Datos. Algo Lento [SOLUCIONADO]
Hola!.

Estuve creando una base de datos de un archivo de texto. Son unos 370 registros y es que tarda un "poco" en crear la base.
No sé si puedo optimizar algo más el código. Me crea la base y la tabla, pero tarda por lo menos casi 2 minutos.

¿ Cómo podría acelerar un poco este código ?.

' gambas module file

Private hcon As Connection
Private basenombre As String = "juegosAmiga.sqlite"

Public Sub Main()

Dim hfile As File
Dim linea As String
Dim ruta As String
Dim re As New RegExp
Dim palabras As New String[]

ruta = Application.Path &/ "listajuegos.txt"
hfile = Open ruta For Input

AbrirBase()
CrearTabla()
hcon.Close()
hcon.Name = basenombre
hcon.Open

While Not Eof(hfile)
Line Input #hfile, linea
If Len(linea) > 1 Then
linea = LTrim(linea)
' No quiero lineas que contengan LISTA,NOMBRE,-
If Not re.Match(linea, "\\A(LISTA|NOMBRE|-)") Then
palabras = Split(Replace(linea, " ", "\n"), "\n", Null, True)
hcon.Exec("insert into juegos values (&1,&2,&3,&4,&5)", Null, Trim(palabras[0]), Trim(palabras[1]), Trim(palabras[2]), Trim(palabras[3]))
Endif
Endif
Wend
Close #hfile
CerrarConexion()

End

Public Sub AbrirBase()

hcon = New Connection
With hcon
.Type = "sqlite3"
.Host = User.Home &/ "Prueba/Bases/"
.Name = ""
End With
hcon.Open

If Not hcon.Databases.Exist(basenombre) Then
hcon.Databases.Add(basenombre)
Wait 0.3
hcon.Close
hcon.Name = basenombre
hcon.Open
Endif

End

Public Sub CrearTabla()

Dim hTable As Table

If Not hcon.Tables.Exist("juegos") Then
hTable = hcon.Tables.Add("juegos")
With hTable.Fields
.Add("idjuego", db.Serial)
.Add("titulo", db.String, 50)
.Add("categoria", db.String, 50)
.Add("discos", db.Integer)
.Add("numdiscos", db.String)
End With
hTable.PrimaryKey = ["idjuego"]
hTable.Update
Endif

End

Public Sub CerrarConexion()

If hcon = Null Then Return
hcon.Close()
hcon = Null

End


¿ Son obligatorios los 30 segundos del wait ?.

perfilado_1432585079_181107

El archivo creado esta entero y solo mide 15K!!!!....me muero si fuera la base 10 veces mas grande.

Saludos

última edición por Shell el Domingo, 31 May 2015, 09:23; editado 2 veces
Objetivo: Re: Creando Una Base De Datos. Algo Lento
"Wait 0.3" son 300 milisegundos, no 30 segundos.

Ese código en principio no debería tardar tanto... no sé que puede ser

Prueba a eliminar la búsqueda mediante expresiones regulares y usa funciones de cadenas normales, las regex son algo lentas...

Saludos

Perfil MP  
Objetivo: Re: Creando Una Base De Datos. Algo Lento
Jesús:

Citar:

"Wait 0.3" son 300 milisegundos, no 30 segundos.


Es verdad, sería lentísimo.

Citar:

Prueba a eliminar la búsqueda mediante expresiones regulares y usa funciones de cadenas normales, las regex son algo lentas...


Ok, lo intentare de esa forma. Son muy cómodas.
No la he aprovechado totalmente. También puede ser compilada, pero no creo que sea necesario.

Este trozo de código puede leer el archivo de texto de la lista de juegos y lo muestra eliminando lineas no deseadas y es rápido.

Public Sub Main()

Dim contenido_archivo As String
Dim linea As String
Dim re As New RegExp

contenido_archivo = File.Load("listajuegos.txt")

For Each linea In Split(contenido_archivo, "\n")
If Len(linea) > 1 Then
linea = LTrim(linea)
' No quiero mostrar lineas que contengan LISTA,NOMBRE,-
If Not re.Match(linea, "\\A(LISTA|NOMBRE|-)") Then Print linea
Endif
Next

End

Preferí leer directamente linea por linea y operar según el contenido.
Era más rápido, que leer el archivo almacenando su contenido en una variable de cadena y luego otra vez más bucles trabajando
con la variable.

Lo malo es que lo hice Python y es que instantáneo. Me ha matao.
Este es el de Python:

#|/usr/bin/python3

import sqlite3
import re

# Prueba de lectura de las listas de juegos de Amiga
fhand = open('listajuegos.txt','r')
lista_total = []

def crear_lista_total():
for line in fhand:
if len(line) > 1:
line = line.strip()
if not re.search(r"\A(LISTA|NOMBRE|-)",line):
line = line.strip()
lista_tmp = []
lista_tmp = line.split(' ')
lista_tmp = eliminar_espacios(lista_tmp)
lista_total.append(lista_tmp)


def eliminar_espacios(lista):
lst = []
for palabra in lista:
if len(palabra) == 0:
continue
else:
lst.append(palabra.strip())
return lst

def crear_base(lista):
# Creacion de la base
db = sqlite3.connect('amigabase.db')
db.row_factory = sqlite3.Row
db.execute('drop table if exists baseamiga')
db.execute('create table baseamiga (nombre text, categoria text, discos integer, numdisco text)')

# Insertar campos en la base de datos
for id in range(len(lista)):
db.execute('insert into baseamiga (nombre, categoria, discos, numdisco) values (?, ?, ?, ?)',( lista[id][0], lista[id][1], lista[id][2], lista[id][3]))

db.commit()


def main():
crear_lista_total()
crear_base(lista_total)

if __name__=="__main__" : main()


Se que pude usar compresión de listas. Tuve que crearme la forma de eliminar los elementos del array que fueran cadenas vacías.

Saludos

Objetivo: Re: Creando Una Base De Datos. Algo Lento
Se puede acelerar el proceso con las ordenes Begin y commit, en teoría.

hcon.begin
While Not Eof(hfile)
.....
.....
Wend
hcon.commit

Sin embargo yo, para ese tipo de manejos prefiero dejar siempre que opere la base de datos, que lo hace inifinitamente más rápido.
Si miras la opción de importar que subí en el programa siesta, verás que, tras construir la tabla, todo se resuelve con una llamada a la base de datos

proceso = Shell "sqlite3 " & dbPath &/ dbName & " </tmp/carga_csv.sql" Wait For Read


Es prácticamente instantánea y la he utilizado con tablas de más de 5.000 registros...

Evidentemente requiere que el ordenador tenga instalado el intérpre sqlite3, cosa que resuelvo añadiéndolo a las dependencias del .deb al construir el paquete de instalación.

Creo haberme quejado ya en algún que otro post de la incomprensible lentitud de gambas para este tipo de manipulaciones... pero sin respuestas, me temo.

última edición por shordi el Martes, 26 May 2015, 09:12; editado 1 vez
Perfil MP  
Objetivo: Re: Creando Una Base De Datos. Algo Lento
Shordi:

Gracias, buscare el programa siesta.

Citar:

Creo haberme quejado ya en algún que otro post de la incomprensible lentitud de gambas para este tipo de manipulaciones... pero sin respuestas, me temo.


La verdad es que siendo aplicación de formulario, aplicaciones de gestión, es fundamental.
Pasa como cuando quieres reproducir un archivo de sonido en gambas, en su día era lento, como
si no fuera la frecuencia adecuada, (como si le faltasen pilas).

Tienes que apuntarte a ayudar a Benoit y a Nigel Gerrard para mejorar el componente de sqlite.
No tiene que ser nada fácil el tema. Si al menos te dan una explicación del posible problema.

Saludos

Objetivo: Re: Creando Una Base De Datos. Algo Lento
Voy a crear un archivo csv a ver si con este puedo trabajar desde linea de comandos con sqlite.

' No usaremos expresiones regulares, usaremos funciones de cadenas

Private ruta_origen As String
Private ruta_destino As String

Public Sub Main()

ruta_origen = Application.Path &/ "lista_juegos_amiga.txt"
ruta_destino = User.Home &/ "Temporales/base_amiga.csv"

If Not Exist(ruta_destino) Then GenerarArchivoCSV()

End

Public Sub GenerarArchivoCSV()

Dim hfile_origen, hfile_destino As File
Dim linea As String
Dim campos As New String[]

hfile_origen = Open ruta_origen For Input
hfile_destino = Open ruta_destino For Output Create

While Not Eof(hfile_origen)
Line Input #hfile_origen, linea
linea = Trim(linea)
If Len(linea) < 1 Then Continue
' No quiero mostrar lineas que contengan LISTA,NOMBRE, "-" como el primer caracter de linea
If (InStr(linea, "LISTA") = 0) And (InStr(linea, "NOMBRE") = 0) And (InStr(linea, "-") <> 1) Then
campos = Split(Replace(linea, " ", "\n"), "\n", Null, True)
Write #hfile_destino, Chr(34) & Trim(campos[0]) & Chr(34)
Write #hfile_destino, ","
Write #hfile_destino, Chr(34) & Trim(campos[1]) & Chr(34)
Write #hfile_destino, ","
Write #hfile_destino, Chr(34) & Trim(campos[2]) & Chr(34)
Write #hfile_destino, ","
Write #hfile_destino, Chr(34) & Trim(campos[3]) & Chr(34)
Write #hfile_destino, "\n"
Endif
Wend
Close #hfile_origen
Close #hfile_destino

End


Que remedio. Antes tengo que cambiarlo y crear como primera linea los nombres de los campos.
Cuando en su día hacía conversiones de csv a sqlite tenía que entrar en la consola de sqlite. Creo que sera posible hacerlo sin entrar.
Tengo que bajar aquí el programa SIESTA. No es muy complicado este ejemplo que hice.

P.d Parece que ha cambiado la sintaxis de Write en Gambas3, donde hace referencia más bien para un Stream. Flujo de datos.

Saludos

Objetivo: Re: Creando Una Base De Datos. Algo Lento
Solo una cosa para yo saber -

La propriedad File.Load -> es la que se usa para llamar los archivos de la base de datos?

Si quieres escoger de dentro de ese .txt que File.Load llama tendrias que cambiar a otra propriedad?

Disculpad molestar continuamente con mis dudas pero asi me voy enterando de cosillas.


Perfil MP  
Objetivo: Re: Creando Una Base De Datos. Algo Lento
portaro:


Citar:
La propriedad File.Load -> es la que se usa para llamar los archivos de la base de datos?

No, se usa para leer archivos de texto
Mirate esto http://cursogambas.blogspot.com.es/...critura-de.html

Para llamar a archivos de bases de datos, tienes que usar la clase Connection
http://cursogambas.blogspot.com.es/...resultados.html

Saludos

Objetivo: Re: Creando Una Base De Datos. Algo Lento
Hola Portaro.

Al principio leía el archivo de la lista_de_juegos.txt y almacenaba el contenido en una variable de cadena. (Con File.Load)
Luego ejecutaba otra vez desde el comienzo un bucle sobre la variable de cadena para realizar
unas operaciones con cada linea almacenada.

El archivo lo tenía que leer de principio a fin, eso era fijo. Y yo estaba haciendo dos veces lo mismo.
Al final, era mejor usar Open, leer cada linea y hacer las operaciones. Una sola lectura.

Como ves, por rapidez vamos hacia File.Load por defecto. Es sencillo y fácil de usar.
La condición de este ejemplo no lo necesitaba y si requería algo más directo.

Moraleja: No te dejes llevar por lo primero que pienses, tomate algo de tiempo.

Como es normal eso lo ves cuando insistes en el mismo código queriendo optimizarlo, cosa que no siempre hacemos.

Saludos.

Objetivo: Re: Creando Una Base De Datos. Algo Lento
Muchas gracias asi aprendo.

Perfil MP  
Ir a la página 1, 2  Siguiente

Página 1 de 2


  
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas
No puede adjuntar archivos
Puede descargar archivos
No puede publicar eventos en el calendario

   

Está utilizando la versión (Lo-Fi). Para ver la versión completa del foro, haga clic aquí.

Powered by Icy Phoenix based on phpBB
Design by DiDiDaDo

Página generada en:: 0.496s (PHP: -48% SQL: 148%)
Consultas SQL: 47 - Debug off - GZIP Activado