Newsgroup: it.comp.lang.visual-basic
Titolo: [Lungo] Vb vs VC i sorgenti incriminati

Come richiesto posto i sorgenti in cui si nota come la gestione di Array di long
in VB č compilata in modo efficiente tanto quanto quella in VC.
Piccola spiegazione:
L'ordinamento č fatto in modo da "fregare" gli altri algoritmi quando l'input lo
permette;
In caso contrario viene invocato QuickSortNumbers (la cui implementazione mi č
stata fornita da Zanna e non č riportata in questo post) con un sovvraccarico di
lavoro dovuto alla scansione dell'array.
Per testarlo correttamente, fare in modo che l'array di input (tipicamente di
valori casuali) non contenga numeri troppo grandi (>16777215 ).
Se avete meno di 256 MB di memoria abbassare proprozionalmente il valore
16777215
Ovviamente il tutto va compilato con ottimizzazione P-pro e rimozione controlli
sui limiti di array.
Sorgente versione totalmente VB. 
------>
Sub linearSort(v() As Long)
Dim lngMax As Long
Dim a As Long ' contatore
Dim b As Long ' contatore
Dim c As Long ' puntatore in scrittura
lngMax = v(LBound(v))
For a = LBound(v) + 1 To UBound(v)
    If v(a) > lngMax Then lngMax = v(a)
Next
If lngMax > 16777215 Then
    ' dovrei dimensionare un array di oltre 16777216 elementi long=128MB
    ' occuperei troppa memoria: chiamo un ordinamento tradizionale
    ' Call QuickSortNumbers(v(), LBound(v), UBound(v))
    Exit Sub
Else
    ReDim buf(0 To lngMax) As Long
    For a = LBound(v) To UBound(v)
        buf(v(a)) = buf(v(a)) + 1
    Next
    For a = LBound(buf) To UBound(buf)
        b = buf(a)
        While b <> 0
            v(c) = a
            c = c + 1
            b = b - 1
        Wend
    Next
End If
End Sub
<----- ' fine sorgente
------> Estratto DLL VC
extern "C" __declspec (dllexport) int __stdcall linearSort( __int32 *Arr,
__int32 First,__int32 Last,  __int32 *BArr, __int32 BFirst,__int32 BLast) 
{
	__int32 a;
	__int32 b; 
	__int32 c; 
	c=First;
	for (a = First; a<= Last; a++)
	{
			BArr[Arr[a]] ++;
	}
	for (a = BFirst; a<= BLast; a++)
	{
		b = BArr[a];
		while (b != 0)
		{
			Arr[c++] = a;
			b --;
		}
	}        
	return 1;
}
extern "C" __declspec (dllexport) long __stdcall maxArray( __int32 *Arr, __int32
First,__int32 Last) 
{
__int32 lngMax;
__int32 a;
lngMax = Arr[First];
for (a = First+ 1; a<=Last; a++)
	{
    if (Arr[a] > lngMax)
		{
		lngMax = Arr[a];
		}
	}
	return lngMax;
}
<------ ' Fine estratto DLL VC
----> Funzione VB per invocare la DLL VC; di inserire in un modulo
Public Declare Function MaxArray Lib "linearSort.dll" Alias "_maxArray@12"
(ByRef arr As Long, ByVal first As Long, ByVal last As Long) As Long
Public Declare Function linearsortCimp Lib "linearSort.dll" Alias
"_linearSort@24" (ByRef arr As Long, ByVal first As Long, ByVal last As Long,
ByRef Barr As Long, ByVal Bfirst As Long, ByVal Blast As Long) As Integer
Sub linearsortC(v() As Long)
Dim lngMax As Long
Dim buf() As Long
lngMax = MaxArray(v(0), LBound(v), UBound(v))
If lngMax > 16777215 Then
	' chiamare quicksortnumbers
Else
    ReDim buf(0 To lngMax) As Long
    linearsortCimp v(0), LBound(v), UBound(v), buf(0), LBound(buf), UBound(buf)
End If
End Sub
<---- ' Fine Funzione VB per invocare la DLL

 mi è stata fornita da Zanna e non è riportata in questo post) 
[...]
Ehm... chiedo venia... mi è stata fornita da Luca Dormio
x:termoPilucco, ops

 Ehm... chiedo venia... mi è stata fornita da Luca Dormio
Ah, ecco... mi stavo giusto chiedendo se te l'avevo poi inviata :)
Io devo smetterla di rispondere dal PC dell'ufficio che appena posso invierò
il materiale, perchè poi mi dimentico e faccio solo figure :P
Ciao
--
Math Parser : 
http://www.neodatatype.net
Sito Comune : 
http://www.it-lang-vb.net

<---- ' Fine Funzione VB per invocare la DLL
Sarebbe interessante appurare come hai fatto la misurazione.
Qui c'e' una perdita di tempo dovuta al caricamento della dll ed al
passaggio di due bei blocchi di memoria rappresentati da v() e buf().
Un confronto corretto penso sarebbe da fare tra un exe tutto vb ed uno
tutto C ( o tutto C++, perché se hai usato extern significa che hai
dovuto ovviare al name mangling del C++).
-- 
ciao, hal

dovuto ovviare al name mangling del C++).
Sì, però siccome la prova doveva dimostrare la bontà della gestione di Vb degli
array di interi (non mi sognerei di affermare che VB è più veloce del C in
ambiti generici), ho delegato a VB stesso il dimensionamento dell'array e il
semplice controllo condizionale sulla convenienza dell'algoritmo.
La parte VB del codice misto viene eseguita una volta sola per ogni chiamata ed
è in comune con la versione VB pura.
In questo modo, esclusa la chiamata alla DLL, le due routine fanno esattamente
la stessa cosa con la differneza che la versione mista delega alla DLL i cicli
di gestione degli array.
x:termoPilucco.

di gestione degli array.
Non mi sembra percio' strano che il vb se la veda con onore contro il
C in questo caso, alla fine il codice binario dovrebbe essere piu' o
meno lo stesso.
Sono in ogni caso d'accordo con te sul fatto che non e' proprio cosi'
vero che il vb sia sempre piu' lento: e' piuttosto vero che lo stesso
programma puo' essere scritto in tanti modi diversi a parita' di
linguaggio, sfruttandone o no i punti di forza.
-- 
ciao, hal

linguaggio, sfruttandone o no i punti di forza.
Esatto.
Per fare grafica o sfruttare al meglio le classi meglio del C++ non si puň
avere.
Per elaborazioni intense e ripetitive l'Assembly sfrutta al meglio anche le
estensioni del processore.
A VB cosa rimane? :)
x:termoPilucco.

 x:termoPilucco.
Sempre IMHO eh!
Saluti :-)

 martellandosi le palle  anche in assembler si potrebbe fare!
Eh eh...
x:termoPilucco.

sia! (ora i Delphini insorgono!)
Non sono un delphino, ma quel poco che ho visto Delphi e' avanti anni
luce a vb6. Peccato che il confronto tra le forze commerciali di
Borland e Microsoft sia impari.
-- 
ciao, hal

 Borland e Microsoft sia impari.
<g>
Sottoscrivo in pieno.
Per chi fosse interessato, puo' chiedere a Luca di Cerneglions, il quale č
venuto a
casa mia ed ha visto Delphi "in action", dicendomi tra l'altro che č quasi
uguale a dotNET <g>.
Ciao,
Andrea

 l'altro che è quasi  uguale a dotNET <g>.
A proposito hai provato a implementare il mio algoritmo per vedere la
velocità in fase di eseguibile?
p.s. non sapevo che Deplhi fosse di Borland, SH che ha la mia massima
ammirazione.
x:termoPilucco.

 Andrea
--
.A  [Microsoft MVP .NET]
UGIdotNET - User Group Italiano .NET
http://www.ugidotnet.org
Read my blog at: 
http://www.ugidotnet.org/4.blog

 x:termoPilucco.
Andrea

 Insertion,etc ) ma qui non riesco a capire... mi dai una mano?
Qui sta il bello.
Niente confronti, niente spostamenti.
supponiamo di voler ordinare larray che contiene 6,3,1,3
1) Trovo il max:  è 6
2) Creo un array di appoggio: A[o to 6]
3) Per ogni elemento dell'array da ordinare aggiungo 1 nell'array di
appoggio proprio in corrispondenza della numero che devo ordinare:
    A[6]=0+1
    A[3]=0+1
    A[1]=0+1
    A[3]=1+1=2
4) Per ogni elemento dell'array di appoggio, se trovo un valore diverso da
zero nella posizione I significa che nell'array originale c'era il numero I
(tante volte quante indicate da A[I]) Per esempio A[3]=2 perchè 3 compariva
due volte nell'array originale.
5) Siccome l'array di appoggio lo scansiono dall'indice 0 in su, mi trovo
gli elementi in ordine!
    A[0]=0 ' non faccio nulla
    A[1]=1 ' il primo elemento ordinato è un 1
    A[2]=0 ' non faccio nulla
    A[3]=2 ' il secondo e il terzo elemento ordinato è un 3
    A[4]=0 ' non faccio nulla
    A[5]=0 ' non faccio nulla
    A[6]=1 ' il quarto elemento ordinato è un 6
Ovviamente se avessi  lngMax molto grande, l'algoritmo non sarebbe
applicabile per questioni di memoria, nè conveniente (infatti chiamo
quicksort).
Però in molti casi il vantaggio è notevole.
x:termoPilucco.

 in VB è compilata in modo efficiente tanto quanto quella in VC.
[cut]
Quando ho un po' più di tempo gli darò una controllata un po' più
approfondita.
Però dal tuo primo post pensavo che il confronto fosse: programma VB vs
programma C(++).
Il caso della dll cambia un po' le cose.
Ciao.
-- 
BSD is for UNIX lovers -- linux is for Windows haters.

Il caso della dll cambia un po' le cose.
Non č cosě fondamentale:
Per ogni chiamata di ordinamento, eseguo due chiamate alla DLL con,
complessivamente, una decina di parametri (tutti long).
Si tratta quindi di qualche decina di cicli di clock per passare da VB a VC
(facciamo anche 1000, non cambia nulla) a fronte dei circa 3 Miliardi di cicli
utilizzati dalla funzione principale, eseguita interamente in VC.
x:termoPilucco.

 utilizzati dalla funzione principale, eseguita interamente in VC.
Beh, per saperlo basta provare...
Fare un programma 100% C (o C++) e verificare i tempi.
