Comunidad Gambas-es
[SOLUCIONADO] Necesito acelerar código, ¿me ayudan? - Versión para impresión

+- Comunidad Gambas-es (https://gambas-es.org)
+-- Foro: Gambas (https://gambas-es.org/forumdisplay.php?fid=3)
+--- Foro: General (https://gambas-es.org/forumdisplay.php?fid=4)
+--- Tema: [SOLUCIONADO] Necesito acelerar código, ¿me ayudan? (/showthread.php?tid=454)

Páginas: 1 2


Necesito acelerar código, ¿me ayudan? - gambafeliz - 11-06-2021

Hola,

Tengo varios problemas de lentitud en varios trozos de código y os voy a poner uno por si me pueden ayudar. Gracias.

¿Sería posible acelerar esto?

GAMBAS
  1. ' cadena por ejemplo se le pasa -32,40 €
  2. Public Function soloNumeros(cadena As String) As String
  3.  
  4. Dim sCadena As String
  5.  
  6. For n = 0 To Len(cadena)
  7. If IsDigit(cadena[n]) Or If cadena[n] = "." Or If cadena[n] = "," Or If cadena[n] = "-" Then sCadena &= cadena[n]
  8. Return IIf(sCadena = "", "0", sCadena)
  9.  





RE: Necesito acelerar código, ¿me ayudan? - vuott - 11-06-2021

Confused ...podemos quitar un elemento:

GAMBAS
  1. If IsDigit(cadena[n]) Or ((Asc(cadena[n]) > 43) And (Asc(cadena[n]) < 47)) Then sCadena &= cadena[n]



...y, si está absolutamente seguro de que el carácter "/" nunca estará presente en la cadena de caracteres entre los números, pasada a la función "soloNumeros()", entonces podemos eliminar un otro elemento:
GAMBAS
  1. If (Asc(cadena[n]) > 43) And (Asc(cadena[n]) < 58) Then sCadena &= cadena[n]





RE: Necesito acelerar código, ¿me ayudan? - Shordi - 11-06-2021

Tras probar varios enfoques, el original es el más rápido... dependiendo de lo que le pongas. Sin embargo como está, supongo, destinado a depurar cadenas cortas casi siempre numéricas, ahí es el más rápido por los atajos decisivos de "or if" porque la mayoría de los caracteres no pasa de isdigit() y no hay que mirar más.

saludos
Código:
 



RE: Necesito acelerar código, ¿me ayudan? - vuott - 11-06-2021

(Ayer, 15:17)vuott escribió:  si está absolutamente seguro de que el carácter "/" nunca estará presente en la cadena de caracteres entre los números

...o mejor:

GAMBAS
  1. Public Function soloNumeros(cadena As String) As String
  2.  
  3.    Dim n As Integer
  4.  
  5.    For n = 0 To Len(cadena)
  6.      If (Asc(cadena[n]) < 44) Or (Asc(cadena[n]) > 57) Then Mid(cadena, n + 1, 1) = Null
  7.    Next
  8.    
  9.    Return cadena
  10.  



...o si prefieres sin la palabra-llave "Return": Big Grin

GAMBAS
  1. Public Sub Main()
  2.  
  3.   Dim cadena As String = "-32.40€"
  4.   Dim bb As New Byte[]
  5.   
  6.   bb = bb.FromString(cadena)
  7.  
  8.   soloNumeros(bb)
  9.   
  10.   Print bb.ToString(0, bb.Find(0))
  11.  
  12. End 
  13.  
  14.  
  15. Private Function soloNumeros(cadena As Byte[])
  16.  
  17.    Dim n As Integer
  18.  
  19.    For n = 0 To cadena.Max
  20.      If (cadena[n] < 44) Or (cadena[n] > 57) Then cadena[n] = 0
  21.    Next
  22.  


Supongo que esta última función entre aquellas mias, no teniendo funciones nativas de cadena, sea la más rápida.


RE: Necesito acelerar código, ¿me ayudan? - cogier - 11-06-2021

La velocidad de esto ya es muy rápida. Tuve que pasar por un millón de ejemplos para obtener un resultado de velocidad razonable. He puesto una solución ligeramente diferente, (If IsNumber(cadena[n]) Then sCadena &= cadena[n]) pero la diferencia de velocidad es insignificante. 

Prueba este código.Tendrás que cambiar el formato del número en la línea 51.

GAMBAS
  1. ' Gambas class file
  2.  
  3. Public Sub Form_Open()
  4.  
  5.   Dim fStart, fFinish As Float
  6.   Dim sData As String[]
  7.   Dim iLoop As Integer
  8.   Dim sNull As String
  9.   
  10.   Me.Center
  11.  
  12.   If Not Exist(Application.Path &/ "data.txt") Then CreateNos
  13.   sData = Split(File.Load(Application.Path &/ "data.txt"), gb.NewLine, "", True)
  14.  
  15.   fStart = CFloat(Now)
  16.  
  17.   For iLoop = 0 To sData.Max
  18.     sNull = soloNumeros(sData[iLoop])
  19.   Next
  20.  
  21.   fFinish = CFloat(Now)
  22.   Print DateDiff(fStart, fFinish, gb.Millisecond) & " milisegundos"
  23.  
  24.  
  25. ' cadena por ejemplo se le pasa -32,40 €
  26. Public Function soloNumeros(cadena As String) As String
  27.  
  28.   Dim sCadena As String
  29.  
  30.   For n = 0 To Len(cadena)
  31.     'If IsDigit(cadena[n]) Or If cadena[n] = "." Or If cadena[n] = "," Or If cadena[n] = "-" Then sCadena &= cadena[n]
  32.     If IsNumber(cadena[n]) Then sCadena &= cadena[n]
  33.   Next
  34.  
  35.   Return IIf(sCadena = "", "0", sCadena)
  36.  
  37.  
  38. Public Sub CreateNos()
  39.  
  40.   Dim iLoop As Integer
  41.   Dim sTemp As String
  42.   Dim sNumbers As New String[]
  43.  
  44.   For iLoop = 0 To 1000000
  45.     sTemp = ""
  46.     If Rand(1, 2) = 1 Then sTemp = "-"
  47.     sTemp &= Str(Rand(0, 99999) / 100)
  48.     sNumbers.Add(Format(sTemp, "#0.00 €")) ''************************************************
  49.   Next
  50.  
  51.   File.Save(Application.Path &/ "data.txt", sNumbers.Join(gb.NewLine))
  52.  





RE: Necesito acelerar código, ¿me ayudan? - gambafeliz - 11-06-2021

Gracias por vuestro esfuerzo. Por Dios, muchisimas gracias chicos. Incluso me he emocionado. GRACIAS.

Tras mirarlo más y gracias a vuestros puntos de vista. Me temo que no es posible acelerarlo más.

1. Necesito que me devuelva obligatoriamente "0" ó la cadena depurada donde solo admito números y su signo así como el punto y la coma.
2. Y sí es posible que este todo tipo de caracteres, intento justo depurar toda cadena para saber si es un número tal como yo lo defino.

Al final he detectado mi problema de lentitud y estoy justo ahora intentando resolverlo. Principalmente es desconocimiento de la base de datos SQLite. Os lo cuento por si detectan algo en mi conversación.

Estoy agrupando importes por su categoría y subcategoría. Pero es para cargar un grid por mes y siempre por el año actual. Tenia que crear varias View en concreto 3 para poder obtener un select final.

Además cuando creaba una vista después al final la destruia para crear el siguiente mes. En fin, esto hacia que un ordenador pensara al menos 4 segundo para cargar 12 meses. Y como me he hecho un pendrive con Debian 10 y así ejecutar Gambas IDE donde yo quiera para disfrutar mi maravilloso Gambas sin limites Smile pues en el pendrive incluso tenia que esperar 1 minuto para ver 12 meses. Una locura. Ojala supiera como acelerar a tope mi pendrive. Esto ocurre en cualquier ordenador, ya lo he probado. Sad

Me acabo de dar cuenta que si guardo el año actual en configuración de la aplicación y cada vez que ejecuto esta opción de 12 meses miro si el año ya lo guardé en configuración y utilizo las vistas sin destruirlas para tan solo cargar un pequeño select para cada mes. Así creo que será incluso instantaneo.

Pero que tontito fue para no verlo.


RE: Necesito acelerar código, ¿me ayudan? - omoreno - 11-06-2021

Hola gambafeliz

Hay que agregar los caracteres en el array simbolos.

GAMBAS
  1. Public Function soloNumeros(cadena As String) As String
  2.   Dim simbolos As String[] = [" ", "€", "$", "¥", "¢", "£"]
  3.   For Each s As String In simbolos
  4.     cadena = Trim(Replace(cadena, S, ""))
  5.   Next  
  6.   cadena = Format(Val(cadena), "0.00")
  7.   Return cadena



Saludos.


RE: Necesito acelerar código, ¿me ayudan? - gambafeliz - 11-06-2021

Gracias omoreno lo voy a mirar Smile


RE: Necesito acelerar código, ¿me ayudan? - vuott - 11-06-2021

De todas formas, debes aclarar qué posibles cadenas se pasan a la función.
¿Cualquier tipo de cadena?
O solo algunas cadenas ? Es decir:
esta forma (por ejemplo) "€3,123" es posible ?
Esta ? "€3,123w"
Esta ? "wsde"
Esta ? "3w,45€"


RE: Necesito acelerar código, ¿me ayudan? - gambafeliz - 11-06-2021

Oye vuott primero lo primero aunque se que no eres Futbolero mi enhorabuenas por ganar tu Selección a Turquía. Bravoooo. Smile

Te cuento esta función le paso hasta arroz con cigalas por que es un mero filtro de campos de mi tabla y simplemente le paso columnas de mi tabla para definir.

Mira vuott aunque en la línea anterior afirmo eso que he dicho, es mentira, y ¿por qué? porque acabo de filtra mi Function que nombro en la pregunta y solo le paso cadenas con posibles números con número, signos (+,-) y símbolos monetarios y veo que nada más. Por lo que lo hago por aquello de por si acaso paso algo que no esperaba. Con lo cual os pido disculpa si os he liado o confundido, por su puesto no era mi intensión. Ya sabéis que os aprecio de verdad.

Espero que te haya contestado todo lo que necesitas, joven.

Saludos.