Autor Tema: [intento de tuto] manejo de array utilizando CopyMemory  (Leído 4315 veces)

0 Usuarios y 1 Visitante están viendo este tema.

LeandroA

  • Administrador
  • Petabyte
  • *****
  • Mensajes: 1128
  • Reputación: +151/-8
    • Ver Perfil
[intento de tuto] manejo de array utilizando CopyMemory
« en: Enero 02, 2010, 09:20:43 pm »
Holas, quiero exponer o intentare hacer algo así como un tuto para manejar array de una forma muy rápida, para mi es algo nuevo ya que nunca me salio. la idea es utilizando el api CopyMemory es muchisimo mas rápido de lo que se puede llamar método tradicional.

vamos por parte
utilizaremos un array de tipo Long

Citar
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function GetTickCount Lib "kernel32.dll" () As Long

Dim Arr() As Long

Private Sub Form_Load()
    Dim i As Long
    ReDim Arr(1000000)
    For i = 0 To 1000000
        Arr(i) = i
    Next
End Sub

nuestro array se llamara Arr()

ahora vamos a intentar eliminar un items de esos 1000001 que posee

el metodo clasico seria
Citar
Private Function RemoveClasic(index As Long)
    Dim i       As Long
    Dim Temp    As Long

    For i = index To UBound(Arr) - 1
        Temp = Arr(i + 1)
        Arr(i) = Temp
    Next
    ReDim Preserve Arr(UBound(Arr) - 1)
End Function

Osea ir meditante un bucle ir cargando el item siguiente al actual, esto es lentisimo si tenemos muchos items.

ahora utilizando CopyMemory
Citar
Private Function Remove(index As Long)
    Dim LenArray As Long
    Dim tArray() As Long
   
    LenArray = UBound(Arr)
    ReDim tArray(LenArray - 1)
   
    If index > 0 Then CopyMemory tArray(0), Arr(0), 4 * index
    CopyMemory tArray(index), Arr(index + 1), 4 * (LenArray - index)
    ReDim Arr(LenArray - 1)
    CopyMemory Arr(0), tArray(0), 4 * LenArray
End Function
el numero 4 que aparece en el codigo es porque trabajamos con una array de tipo Long si fuera byte utilizariamos un 2, si fuera un type LenB(elTipo) o bien contamos a dedos  :)
Realmente no probre esto con Strings no estoy seguro que funcione, si alguien lo prueba o sabe, que cuente si da resultado.
lo que hace es ir copiando segmentos enteros del array a uno temporal, la primera parte es la anterior del item a eliminar y luego la posterior, y por final copiar el temporal al array original.

Insertar un item (por la mitad del array por ejemplo, no al final)
Citar
Private Function Insert(index As Long, Value As Long)
    Dim LenArray As Long
    Dim tArray() As Long
   
    LenArray = UBound(Arr) + 1
   
    ReDim tArray(LenArray)
    If index > 0 Then CopyMemory tArray(0), Arr(0), 4 * index
    tArray(index) = Value
    CopyMemory tArray(index + 1), Arr(index), 4 * (LenArray - index)
    ReDim Arr(LenArray)
    CopyMemory Arr(0), tArray(0), 4 * (LenArray + 1)
End Function

comprobar si un item existe
Citar
Private Function ItemExist(key As Long) As Boolean
    Dim i       As Long
    For i = 0 To UBound(Arr)
        If Arr(i) = key Then: ItemExist = True: Exit For
    Next
End Function
esto es de la forma tradicional, no encontre una forma mas rapida. pero quiero alcarar los siguiente:
si declaramos i dentro de la funcion es mas rapido que si lo declaramos en el general.
si usamos if then en una sola linea es mas rapido.


el codigo completo
Código: [Seleccionar]
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function GetTickCount Lib "kernel32.dll" () As Long

Dim Arr() As Long

Private Sub Form_Load()
    Dim i As Long
    ReDim Arr(1000000)
    For i = 0 To 1000000
        Arr(i) = i
    Next
End Sub

Private Sub Command1_Click()
    Dim StartTime As Long
    Dim i As Long
   
    StartTime = GetTickCount
   
    For i = 0 To 100
        ItemExist 1000000 '<1000000 el peor de los casos
    Next
   
    Debug.Print GetTickCount - StartTime
End Sub

Private Sub Command2_Click()
    'Dim StartTime    As Long
    Dim i           As Long
    'StartTime = GetTickCount
   
    'For i = 0 To 100
        Remove 0
    'Next
   
    For i = 0 To 10
        Debug.Print Arr(i)
    Next
    'Debug.Print GetTickCount - StartTime
End Sub

Private Sub Command3_Click()
    Dim i As Long
   
    Insert 5, 666666

    For i = 0 To 10
        Debug.Print Arr(i)
    Next
End Sub

Private Function ItemExist(key As Long) As Boolean
    Dim i       As Long
    For i = 0 To UBound(Arr)
        If Arr(i) = key Then: ItemExist = True: Exit For
    Next
End Function

Private Function Remove(Index As Long)
    Dim LenArray As Long
    Dim tArray() As Long
   
    LenArray = UBound(Arr)
    ReDim tArray(LenArray - 1)
   
    If Index > 0 Then CopyMemory tArray(0), Arr(0), 4 * Index
    CopyMemory tArray(Index), Arr(Index + 1), 4 * (LenArray - Index)
    ReDim Arr(LenArray - 1)
    CopyMemory Arr(0), tArray(0), 4 * LenArray
End Function

Private Function Insert(Index As Long, Value As Long)
    Dim LenArray As Long
    Dim tArray() As Long
   
    LenArray = UBound(Arr) + 1
   
    ReDim tArray(LenArray)
    If Index > 0 Then CopyMemory tArray(0), Arr(0), 4 * Index
    tArray(Index) = Value
    CopyMemory tArray(Index + 1), Arr(Index), 4 * (LenArray - Index)
    ReDim Arr(LenArray)
    CopyMemory Arr(0), tArray(0), 4 * (LenArray + 1)
End Function

hice unas pruebas con Coleciones y son muchas mas lentas que usar array , lo unico es mas raipido a la hora de intentar accerder a un item atraves de las key

Despedida:
Este tuto es mas dificil de entender que intentar tipear una capcha en chino basico.
si dije muchas pabadas no peguen fuerte  :P

raul338

  • Terabyte
  • *****
  • Mensajes: 894
  • Reputación: +62/-8
  • xD fan!!!!! xD
    • Ver Perfil
    • Raul's Weblog
Re:[intento de tuto] manejo de array utilizando CopyMemory
« Respuesta #1 en: Enero 02, 2010, 11:24:55 pm »
Este tuto es mas dificil de entender que intentar tipear una capcha en chino basico.

dificil? mas facil imposible  ;)
Te salio bien, y esta muy bueno esto de copiar y pegar memoria, nunca se me hubiera ocurrido.

Agregado A marcadores!

Aver cuando sale el proximo tuto  ::)

xmbeat

  • Kilobyte
  • **
  • Mensajes: 84
  • Reputación: +3/-1
  • la vida no tiene sentido sin Dios
    • Ver Perfil
Re:[intento de tuto] manejo de array utilizando CopyMemory
« Respuesta #2 en: Enero 06, 2010, 08:21:18 pm »
me parecio bueno y bien explicado el tuto, sigue asi, esperamos mas tuto de Apis ;D
El hombre encuentra a Dios detrás de cada puerta que la ciencia logra abrir. -Einstein