PDA

Visualizza versione completa : Chi me lo ottimizza ?


LoryOne
06-11-2003, 16.59.57
Ecco il codice:


Option Explicit
Dim Caratteri(32 To 255) As Long

Private Function Func_ContaStringa(ByVal S As String, Optional ByVal Delimiter As String = ",") As Long
'Conta quante volte una sottostringa è contenuta all'interno di una stringa
'Ogni elemento è separato da un delimitatore
Dim Ty As Long, Yt As Long, Yy As Long, Conta As Long

Ty = InStr(S, Delimiter)
Yt = Len(Delimiter)
While Ty
Conta = Conta + 1
Yy = Ty + Yt
Ty = InStr(Yy, S, Delimiter)
Wend
Func_ContaStringa = Conta
End Function

Private Function Func_Contaparole(ByVal S As String, Optional ByVal Delimiter As String = " ") As Long
'Conta le parole.
Dim Ty As Long, Yt As Long, Yy As Long, Conta As Long

S = Trim$[S]
If Len[S] Then
Ty = InStr(S, Delimiter)
Yt = Len(Delimiter)
While Ty
If Asc(Mid$(S, Ty + 1, 1)) <> 32 Then Conta = Conta + 1
Yy = Ty + Yt
Ty = InStr(Yy, S, Delimiter)
Wend
Func_Contaparole = Conta + 1
End If
End Function

Private Sub Command1_Click()
Dim A As Integer, TotCaratteri As Long, Ty As Long
Dim S As String, S1 As String * 50, S2 As String * 1
Dim T1 As Single, T2 As Single

S = RichTextBox1.Text
Screen.MousePointer = vbHourglass
T1 = Timer

With List1
.Clear
For A = 32 To 255
Select Case A
'Scarta i caratteri non testuali
Case 95, 96, 127 To 144, 147 To 159
Case Else
S2 = Chr$(A)
Ty = Func_ContaStringa(S, S2)
Caratteri(A) = Ty
TotCaratteri = TotCaratteri + Caratteri(A)
S1 = "Carattere '" & S2 & "' contenuto " & Caratteri(A) & " volte"
.AddItem S1
End Select
Next
End With
Ty = Func_Contaparole[S]

T2 = Timer

Screen.MousePointer = vbNormal

Label1 = "Vi sono " & Format$(TotCaratteri, "###,0") & " caratteri"
Label3 = "Vi sono " & Format$(Ty, "###,0") & " parole"
Label2 = "Completato in " & T2 - T1 & " secondi."
End Sub

Private Sub Command2_Click()
Dim S As String

S = InputBox("Nome file :", "Immetti il nome del file di testo")
If Len(Trim$[S]) = 0 Then S = App.Path & "\license.txt"
RichTextBox1.filename = S
End Sub

Private Sub Form_Load()
Command1.Caption = "Esegui"
Command2.Caption = "File"
End Sub

Private Sub Text1_KeyPress(KeyAscii As Integer)
MsgBox "Contenuto " & Caratteri(KeyAscii) & " volte"
End Sub


Il programmino conta il numero di parole contenute in un testo, nonchè il numero di volte che ogni singolo carattere che lo compone è presente in esso.
Avrete bisogno di

1 richtextbox
1 listbox
3 label
1 textbox
2 commandbutton

Il programma è stato compilato in codice nativo (VB5.0).
Esso è portabile (a mio avviso) con facilità sotto altri linguaggi.
Sarebbe interessante evidenziare le differenze velocistiche, secondo me, in fondo non così rilevanti.

Saluti ;)

pholcus
06-11-2003, 18.45.34
Direi che il file txt allegato e' troppo piccolo x provare le prestazioni di questo programma ;)

Provo a farlo in java e in c..

Ciao

pholcus
06-11-2003, 18.48.49
Prova con questo file..a me impiega circa 11 secondi..

LoryOne
06-11-2003, 22.31.36
Ho scaricato il file che hai postato.
Tra 8,95 e 9,11 secondi su un Athlon Tb 1,2 GHz.

Ho apportato leggere modifiche:

1) Eliminato le flex strings, ossia i Dim S as string* ed ho lasciato Dim S as string

Mi sembra accettabile come tempo, comunque aspetto la versione Visual C++/Delphi.

LoryOne
07-11-2003, 10.44.17
Leggera modifica nella concatenazione di stringhe.

S1 = "Carattere '" & S2 & ("' contenuto " & (Caratteri(A) & " volte"))

Si nota un leggero aumento prestazionale solo nell'inserimento del testo nella listbox, niente di eccezionale, comunque.

pholcus
07-11-2003, 16.12.30
Prova questo in java..
Rinominalo togliendo l'estensione .zip, poi lo lanci con: java -jar regex.jar

Ciao

LoryOne
07-11-2003, 18.26.07
Si, in effetti c'è molta differenza.
Potresti postare il sorgente per piacere ?

pholcus
07-11-2003, 19.58.12
eccolo..non e' il massimo, perche' l'ho fatto in fretta con JBuilder..rinomina in .java ;)

LoryOne
07-11-2003, 23.06.38
0,909 secondi contro 3,350 secondi.

Non vi è dubbio che le performances attuali risultino a favore di Java ma ci sono alcune considerazioni da fare:

1) Nella prima versione del programma, i parametri alla funzione di conteggio dei caratteri contenuti venivano passati ByVal[ue].
Questo implicava una copia del parametro con conseguente perdita di tempo prezioso.
La soluzione è stata quella di passare il parametro ByRef[erence] (Vedi Java)
Tale operazione mi ha fatto risparmiare ben 6 secondi.

2) Io non ho potuto utilizzare la funzione Split di VB6.0, quindi per ricavare il numero di parole (sequenze di caratteri separati da uno o più spazi), ho dovuto implementare la funzione apposita.
Di conseguenza, la funzione Split di Java non doveva essere utilizzata.

3) Nell'implementazione della funzione di cui sopra, è necessario considerare che una parola è un insieme di caratteri separati da un solo spazio, non da più spazi consecutivi.
(A dire il vero, una parola non deve contenere ne punteggiatura ne numeri, comunque...)
L'unico baco alla funzione Func_ContaParole è che una stringa del genere:
"Io mi chiamo LoryOne ."
fornirà come risultato 5 e non 4.
Per la cronaca, persino il "glorioso" Microsoft Word è afflitto da questo baco.

4) Il tempo da considerare è da quando si è premuto il pulsante a quando si è ricavato il numero di parole contenute nel testo, facendo attenzione che nello stesso ciclo (da 32 a 255) venga inserito nella listbox il numero di volte che il carattere in questione compare nel testo da scansionare.

Ciao :)

pholcus
08-11-2003, 10.17.07
Ciao..
beh, hai ragione, non ho portato il codice da vb a java, semplicemente perche' di vb non ne capisco gran che. Era solo x far vedere una possibile miglior implementazione dell'algoritmo..

2) Avrei potuto usare StringTokenizer, ma mi sembrava + macchinoso ;)

3) Ho notato anch'io questa cosa..ma mi vien da pensare che nella mia implementazione sia un baco di split...sto cercando una soluzione..

Ciao

pholcus
08-11-2003, 18.40.31
3) corretto, ho aggiunto un controllo..