Array ed Indici in VB

La settimana scorsa, durante la pausa pranzo, parlavo con alcuni colleghi del più e del meno.
Parlare con me però significa quasi sempre parlare di informatica.
E’ venuto fuori il solito discorso sulla programmazione ed in particolare si è parlato di Visual Basic.

Il VB, come anche altri linguaggi interpretati, è uno strumento che consente di ottenere soluzioni valide scrivendo poche righe di codice. L’ideale per implementazioni veloci ad hoc.
Durante la breve chiacchierata mi è stata rivolta questa domanda:

Gli indici di un array in vb partono da zero a meno di non specificare il contrario. Ma non sarebbe più semplice se partissero da uno?

E’ seguito un breve silenzio ed un sorriso da parte mia. Odio le persone che rispondono alle domande con altre domande ma questa volta è capitato a me che replico:

Conosci l’assembly?

Come risposta è veramente antipatica e poco professionale.
Il fatto è che se durante la pausa pranzo, incomincio a parlare di registri, locazioni di memoria e contatori, la gente mi guarda male e finisce per dire: “ma perchè ho fatto questa domanda?”
Lo ammetto, la sintesi non è il mio forte.

Comunque sia, chi ha studiato l’assembly conosce bene il motivo per cui gli array, a meno di non specificare diversamente, partono con indici pari a zero.
Alla fine della pausa pranzo, avevo già in mente un piccolo test per fare una dimostrazione.

Di seguito riporto due procedure scritte in Visual Basic che lasciano il tempo che trovano. Si tratta di poche righe che non hanno alcuna pretesa ma che secondo me possono rendere l’idea.

Option Explicit

Sub test1()
Dim j(0 To 9) As Long
Dim x As Integer
Dim Conta As Long
Dim Time1 As Date
Dim Time2 As Date

Time1 = Now
Time2 = DateAdd(“s”, 60, Time1)
Conta = 0
While Now < Time2
  For x = LBound(j) To UBound(j)
    j(x) = Conta
    Conta = Conta + 1
  Next
Wend
MsgBox Conta
End Sub

Sub test2()
Dim j(1 To 10) As Long
Dim x As Integer
Dim Conta As Long
Dim Time1 As Date
Dim Time2 As Date

Time1 = Now
Time2 = DateAdd(“s”, 60, Time1)
Conta = 0
While Now < Time2
  For x = LBound(j) To UBound(j)
    j(x) = Conta
    Conta = Conta + 1
  Next
Wend
MsgBox Conta
End Sub

test1 e test2 sono 2 procedure identiche, si differenziano solamente per la dichiarazione dell’array j che per test1 va da 0 a 9 mentre per test2 va da 1 a 10. Sempre 10 elementi per entrambi gli array.
Vinene chiesto al programma di eseguire un ciclo per la durata di un minuto. In detto ciclo una variabile viene costantemente sommata ad 1 come fosse un contatore. Alla fine della esecuzione, viene mostrato all’utente il numero di volte che è stato eseguito il ciclo. Poichè ad ogni iterazione viene aggiornato un elemento diverso dell’array, il numero di volte che il ciclo viene eseguito dipende anche dall’array stesso.

Proviamo adesso ad eseguire test1 e successivamente test2 prendendo nota del valore di Conta alla fine di ogni esecuzione.

Nel mio caso, il valore per test1 è stato 329.842.430 mentre per test2 è stato 326.544.260.
E’ inutile dire che il valore dipende dalla velocità del processore e del sistema operativo ma quello che a noi interessa non è il valore assoluto ma la semplice differenza.

Durante la prova dunque, test1 è stato più veloce di test2 perchè ha eseguito 3.298.170 cicli in più.

Questo può sembrare banale ad un programmatore di visual basic, sopratutto ora che i processori sono molto veloci e la memoria non è più un problema.
In ambienti in cui la velocità è molto importante però, l’attenzione del programmatore è un aspetto da non sottovalutare. C’è da dire comunque che chi vuole ottenere la massima velocità dal processore non si affida certo a vb.

Mi capita però di vedere in giro codice bizzarro e ridondante come ad esempio:

if blVar = true then …

Che senso ha testare se VERO è uguale a VERO oppure VERO è uguale a FALSO? E’ più semplice testare la condizione con:

if blVar then …

L’esecuzione risulterà sicuramente più veloce.

Abbiamo eseguito il test ma non abbiamo ancora dimostrato perchè gli array con indice iniziale pari a zero sono più veloci degli altri.
Per fare le cose come si deve, avrei dovuto prendere un disassemblatore e portarmi nel punto in cui avviene l’esecuzione delle due procedure per analizzarne il contenuto.

Ma questo non è un documento tecnico e non vuole essere una lezione di assembly.

Chi volesse approfondire l’argomento può leggere il quinto capitolo presente in: The Art Of Assembly un libro che per me è stato fondamentale e che può essere scaricato dal link riportato alla fine di questo articolo.
Ed è proprio dal quinto capitolo di questo meraviglioso libro che prendiamo spunto per dare la dostra spiegazione.

Come è possibile vedere dalla immagine riportata in alto, la memoria viene vista dal computer come una grande pila di mattoncini. Ogni mattoncino è una locazione di memoria delle dimenzioni necessarie per conservare la variabile (nel nostro esempio l’array è composto da 10 elementi di tipo Long. In questo caso ogni mattoncino rappresenta 4 byte).

Di consenguenza, per accedere ad un elemento dell’array è necessario applicare la seguente formula:

Element_Address = Base_Address + ((Index – Initial_Index) * Element_Size)

Base_Address è l’indirizzo di memoria da cui parte l’array, Index è l’indice dell’elemento che ci interessa, Initial_Index è l’indice del primo elemento dell’array ed Element_Size è la dimensione occupata in memoria da ciascun elemento.
Se l’indice iniziale dell’array è zero, allora la formula può essere semplificata nel modo seguente:

Element_Address = Base_Address + (Index * Element_Size)

Per questo motivo è preferibile utilizzare array con indici iniziali pari a zero.

Per saperne di più:

The Art Of Assembly (download formato pdf)
Visual Basic Array Tutorial

Leave a comment

2 Comments.

  1. Tutto vero dal punto di vista della programmazione.
    Da un punto di vista pratico, l’esecuzione del test una sola volta può portare a risultati fuorvianti.

    Se, come me, al primo tentativo ottenete un risultato opposto a quanto previsto, non date addosso a Vittorio…l’inconveniente può dipendere da molti fattori diversi.
    Ripetete l’esperimento un po’ di volte e MEDIAMENTE troverete risultati in accordo con la teoria.

Leave a Reply


[ Ctrl + Enter ]