Páginas (3):    1 2 3
Shordi   13-05-2023, 11:48
#21
Tan solo unas pequeñas precisiones sobre mi algoritmo:

Código:
Private Sub getkey() As String

  Static nkey As Integer
  Dim sOffset As String

  Inc nkey
  If nkey > 99999 Then nkey = 0
  sOffset = Right("00000" & Str(nkey), 5)
  Return Format(Now(), "yyyymmddhhnnssuu") & sOffset

1- El format con los años primeros, perfecto, permite ordenar claves (Aunque esto me recuerda a lo que siempre me decía el alemán con quien colaboré sobre el cliente FTP: "¡Pero eso no estaba en las condiciones del proyecto!" y a lo que yo respondía "Sin improvisación no es divertido"...)

2- El lugar "natural" de GetKey es dentro de un módulo, de manera que sea accesible desde cualquier parte del proyecto donde se use. Por tanto la función debe devolver el valor para que sea recogido y aplicado en la clase desde donde se le llame.

2- Se declara STATIC nkey para que una vez se establezca el valor, la secuencia continue ininterrumpida a todo lo largo de la sesión del proyecto que use la función. Dicha secuencia es resetada cada 99999 claves generadas en la sesión y lo limité el offset a eso por no hacer la clave muy larga... pero visto la longitud de las claves de los otros algoritmos, pues se puede ampliar todo lo que se quiera.

      En el retoque de Tincho también se declaran STATIC LastKey (útima clave generada) y sCurrKeyTkey (Control de timestamp duplicados) y se resetea el offset cada cambio de éste último. Es otra forma de hacerlo totalmente válida, por supuesto, pero de cuya utilidad no estoy muy seguro.

Respecto a los Tests propuesto por Tincho, observo que a medida que crece el array de claves se enlentece el proceso, claro. Por tanto, una vez que estamos seguros que la función getkey funciona perfectamente y no es necesaria ninguna comprobación, si cambiamos el código a ésto:
Código:
Public Sub Button2_Click()

  Dim a As New String[]
  Dim skey As String
  Dim t1, t2 As Float
  Dim i As Integer

  TextArea1.text &= "\n\n Conteo por tiempo"
  t1 = Timer
  While True
    skey = getkey()
    Inc i
    t2 = Timer - t1
    If t2 > vbSegundos.Value Then Break
  Wend
  TextArea1.text &= "\nClaves únicas obtenidas por segundo " & Str(i / vbSegundos.Value)

La velocidad de generación pasa de más o menos 20.000 por segundo y disminuyendo... a 1.350.000 por segundo de manera constante. Si eliminamos la necesidad de que todas las claves sean iguales de largas, es decir:

Código:
Private Sub getkey() As String

  Static nkey As Integer
 
  Inc nkey
  Return Format(Now(), "yyyymmddhhnnssuu") & nkey)

End

Entonces la velocidad de generación de claves únicas asciende por encima de 1.500.000 por segundo, suficiente para TercoIde, supongo Big Grin Big Grin .

Adjunto un proyectito que muestra esto:
[Imagen: rgf9KZI.png]

Saludos
Archivos adjuntos
.gz
sample-uuid-contest-0.0.3.tar.gz (Tamaño: 13.37 KB Descargas: 2)
Última modificación: 13-05-2023, 11:54 por Shordi.

No podemos regresar
tincho   13-05-2023, 14:15
#22
(13-05-2023, 11:48)Shordi escribió: En el retoque de Tincho también se declaran STATIC LastKey (útima clave generada) y sCurrKeyTkey (Control de timestamp duplicados) y se resetea el offset cada cambio de éste último. Es otra forma de hacerlo totalmente válida, por supuesto, pero de cuya utilidad no estoy muy seguro.

Es para controlar la cantidad de nkey, ya que si la fecha cambia no tiene ningún sentido que nKey continúe aumentando, me parece mas prolijo y ordenado que cada vez que cambie la marca temporal este tenga un nKey = 0. Pero si la velocidad es la prioridad el método sin ninguna comprobación es el mejor.

1 Saludo.
tincho   14-05-2023, 23:35
#23
Vuott paso un código en la lista de correo que usa la librería estándar libc.
Tome ese código y lo adapte un poco para usarlo como función, el rendimiento es excelente solo el doble de tiempo que el ID de Shordi .

Código:
' Gambas class file

Export

Library "libc:6"

' void srand (unsigned int __seed)
' Seed the random number generator with the given number.
'Private Extern srand(__seed As Integer)

' int rand (void)
' Return a random integer between 0 and RAND_MAX inclusive.
Private Extern rand_C() As Integer Exec "rand"

Static Public Sub Gen() As String

  ' "01/01/1970" is Unix Time Stamp - Epoch:
  Dim i As Integer
  Dim iRan As New Integer[]

  'srand(DateDiff("01/01/1970", Now, gb.Second))

  iRan.Clear

  For i = 0 To 5
    iRan.Add((Lsl(rand_C() And &03, 30)) Or (Lsl(rand_C() And &7fff, 15)) Or (rand_C() And &7fff))
  Next

  Return Hex(iRan[0], 8) & "-" & Hex(iRan[1] And &ffff&, 4) & "-" & Hex((iRan[2] And &0fff) Or &4000, 4) & "-" & Hex((iRan[3] And &3fff) + &8000, 4) & "-" & Hex(iRan[4] And &ffff&, 4) & Hex(iRan[5], 8)

End

' Private Function Rand32() As Integer
'
'   Return (Lsl(rand_C() And &03, 30)) Or (Lsl(rand_C() And &7fff, 15)) Or (rand_C() And &7fff)
'
' End

1 Saludo.
Páginas (3):    1 2 3
  
Usuarios navegando en este tema: 2 invitado(s)
Powered By MyBB, © 2002-2024 MyBB Group.
Made with by Curves UI.