Calcolare tempo esecuzione codice
Hai un problema con Excel? 
Calcolare tempo esecuzione codice...
di cromagno data: 08/09/2015 22:23:33
Buonasera a tutti,
ieri, in altro forum si chiedeva se esistesse un modo per calcolare la velocità di esecuzione di una formula/codice rispetto ad un altra.
Mi è venuto in mente un semplice codice che avevo già utilizzato (riportato sotto) e che per quell'occasione aveva funzionato bene.
Nel proporre però l'esempio, quindi come riportato nel codice, il risultato ottenuto è sempre pari a zero.
In effetti non c'è nulla da elaborare, ma possibile che sia istantaneo???
Oppure c'è un limite... in tempo, sotto al quale per la funzione Timer è praticamente la stessa cifra (secondi)???
Ho provato diversi "escamotage" ma il risultato è stato sempre quello, quindi la domanda che ho fatto mi sembra essere l'unica alternativa....
Sbaglio qualcosa?
Grazie in anticipo a chi risponderà
Sub tempo()
Dim start As Double, fine As Double, tempo As Double
start = Timer
'da mettere il proprio codice (o funzione tramite "Evaluate")
fine = Timer
tempo = fine - start
MsgBox "L'esecuzione è durata " & tempo & " sec."
End Sub |
di scossa data: 08/09/2015 23:17:24
cit.: "... se esistesse un modo per calcolare la velocità di esecuzione di una formula/codice rispetto ad un altra ..."
Ma vorresti valutarlo sul calcolo di una sola formula?
per esempio Evaluate ("SUM(A1:A10)")
sul mio pc impiegherebbe meno di un millesimo di secondo: non puoi misurarlo con Timer
Devi fare un ciclo: con il codice sotto, sul mio pc 0,1875 secondi
Oppure usare le funzioni della libreria del kernel, ma comunque dovresti comunque fare più letture per minimizzare i tempi "spuri", per cui il codice sotto è sufficientemente preciso (dividi per il numero di iterazioni e avrai il tempo medio della singola operazione)
| scossa's web site |
| Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee.(George Bernard Shaw) |
Public Sub Timer_Test2()
Dim nStart As Single
Dim nStop As Single
Dim j As Long
nStart = Timer
For j = 1 To 1000
Evaluate ("SUM(A1:A10)")
Next
nStop = Timer - nStart
Range("B1").Value = nStop
End Sub
|
di cromagno data: 08/09/2015 23:55:45
Esattamente scossa...
la mia domanda era proprio come visualizzare quel "milli/microsecondo".
Anche se credo che tu mi abbia già risposto dicendo che:
"non puoi misurarlo con Timer"
[EDIT]
cmq si, col ciclo For puoi fare una media che risulterebbe più vicina al tempo reale dell'esecuzione della singola formula (certo, in base al ciclo).
Grazie scossa
di scossa data: 09/09/2015 09:18:24
cit.: "la mia domanda era proprio come visualizzare quel "milli/microsecondo"."
Come dicevo devi usare le funzioni della libreria del kernel.
Qui sotto trovi la funzione MicroTimer (tovata in rete ai tmepi che fu ...)
Inserisci tutto in modulo standard.
| scossa's web site |
| Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee.(George Bernard Shaw) |
'-------------- copy & paste in a standard module ---------------
'
'MicroTimer function
'Found on the net
'
Private Declare Function getFrequency _
Lib "kernel32" _
Alias "QueryPerformanceFrequency" ( _
cyFrequency As Currency) _
As Long
Private Declare Function getTickCount _
Lib "kernel32" _
Alias "QueryPerformanceCounter" _
(cyTickCount As Currency) _
As Long
Public Function MicroTimer() As Double
Dim cyTicks1 As Currency
Static cyFrequency As Currency
MicroTimer = 0
If cyFrequency = 0 Then getFrequency cyFrequency
getTickCount cyTicks1
If cyFrequency Then MicroTimer = cyTicks1 / cyFrequency
End Function
'------------------- end copy ----------------
'example to test function MicroTimer
Public Sub Timer_Test()
Dim dTime As Double
Dim nTime As Double
Dim j As Long
dTime = MicroTimer
For j = 1 To 1
Evaluate ("SUM(A1:A10)")
Next
nTime = MicroTimer - dTime
Range("B1").Value = nTime
Range("C1").Value = nTime / 86400
Range("C1").NumberFormat = "[m]:ss.000"
End Sub |
di ninai data: 09/09/2015 09:36:33
ciao
dicendola terra terra, uno come me, per sapere fra due o più formule quale è la più veloce, cosa deve farne del codice???
es. copio il codice in un modulo di un file vuoto, poi inserisco le varie formule ed avvio la macro???
oppure.......
di scossa data: 09/09/2015 09:53:38
cit. ninai: "es. copio il codice in un modulo di un file vuoto, poi inserisco le varie formule ed avvio la macro???"
in un modulo standard (F11 -> menu Inserisci -> modulo) incolli tutto il codice sotto riportato.
Poi nella cella E1 scrivi la tua formula da valutare, p.e.: SOMMA(A1:A100) e poi lanci la macro.
| scossa's web site |
| Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee.(George Bernard Shaw) |
Public Sub Timer_Test()
Dim dTime As Double
Dim nTime As Double
Dim j As Long
Dim n As Long
n = 1 'cambiare con valore a piacere per effettuare più iterazioni
dTime = MicroTimer
For j = 1 To n
[E1] 'cella che contiene la formula da valutare
Next
nTime = MicroTimer - dTime
Range("B1").Value = nTime
Range("C1").Value = nTime / 86400
Range("C1").NumberFormat = "[m]:ss.000"
End Sub
|
di scossa data: 09/09/2015 09:54:44
Edit: riposto tutto il codice da incollare.
| scossa's web site |
Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw) |
'-------------- copy & paste in a standard module ---------------
'
'MicroTimer function
'Found on the net
'
Private Declare Function getFrequency _
Lib "kernel32" _
Alias "QueryPerformanceFrequency" ( _
cyFrequency As Currency) _
As Long
Private Declare Function getTickCount _
Lib "kernel32" _
Alias "QueryPerformanceCounter" _
(cyTickCount As Currency) _
As Long
Public Function MicroTimer() As Double
Dim cyTicks1 As Currency
Static cyFrequency As Currency
MicroTimer = 0
If cyFrequency = 0 Then getFrequency cyFrequency
getTickCount cyTicks1
If cyFrequency Then MicroTimer = cyTicks1 / cyFrequency
End Function
'------------------- end copy ----------------
'example to test function MicroTimer
Public Sub Timer_Test()
Dim dTime As Double
Dim nTime As Double
Dim j As Long
dTime = MicroTimer
For j = 1 To 1
[E1]
Next
nTime = MicroTimer - dTime
Range("B1").Value = nTime
Range("C1").Value = nTime / 86400
Range("C1").NumberFormat = "[m]:ss.000"
End Sub
|
di ninai data: 09/09/2015 10:47:16
grazie scossa
ma di da errore di compilazione:
"il codice del progetto deve essere aggiornato per l'utilizzo in sistemi a 64 bit. Esaminare e aggiornare le informazioni declare, quindi contrassegnarle con l'attributo PtrSafe"
e poi il nome della macro mi sembra anomalo
'cronometra tempi di esecuzione formule.xlsm'!Modulo1.Timer_Test
sbaglierò qualcosa di sicuro
mi chiedevo inoltre
inserendo formule che fanno ,ovviamente, riferimento a celle , dati, e/o fogli presenti in altri file, la cosa non perturba la misurazione???
di scossa data: 09/09/2015 11:42:48
cit.: "ma di da errore di compilazione"
Sostituisci il tutto con quanto sotto.
| scossa's web site |
Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw) |
'-------------- copy & paste in a standard module ---------------
'
'MicroTimer function
'Found on the net
'
#If VBA7 Then
Private Declare PtrSafe Function getFrequency _
Lib "kernel32" _
Alias "QueryPerformanceFrequency" ( _
cyFrequency As Currency) _
As Long
Private Declare PtrSafe Function getTickCount _
Lib "kernel32" _
Alias "QueryPerformanceCounter" _
(cyTickCount As Currency) _
As Long
#Else
Private Declare Function getFrequency _
Lib "kernel32" _
Alias "QueryPerformanceFrequency" ( _
cyFrequency As Currency) _
As Long
Private Declare Function getTickCount _
Lib "kernel32" _
Alias "QueryPerformanceCounter" _
(cyTickCount As Currency) _
As Long
#End If
Public Function MicroTimer() As Double
Dim cyTicks1 As Currency
Static cyFrequency As Currency
MicroTimer = 0
If cyFrequency = 0 Then getFrequency cyFrequency
getTickCount cyTicks1
If cyFrequency Then MicroTimer = cyTicks1 / cyFrequency
End Function
'------------------- end copy ----------------
'example to test function MicroTimer
Public Sub Timer_Test()
Dim dTime As Double
Dim nTime As Double
Dim j As Long
Dim n As Long
n = 100 'cambiare con valore a piacere per effettuare più iterazioni
dTime = MicroTimer
For j = 1 To n
[E1] 'cella che contiene la formula da valutare
Next
nTime = MicroTimer - dTime
Range("B1").Value = nTime
Range("C1").Value = nTime / 86400
Range("C1").NumberFormat = "[m]:ss.000"
End Sub |
di scossa data: 09/09/2015 11:53:59
cit.: "inserendo formule che fanno ,ovviamente, riferimento a celle , dati, e/o fogli presenti in altri file, la cosa non perturba la misurazione???"
N.B.: non parte nessun cronometro o processo che interferisca con la valutazione della formula.
Tu inserisci in una cella la formula;
lanci la macro;
viene memorizzato in una variabile il tempo (al microsecondo) di inizio della valutazione ;
la formula nella cella viene valutata (per quanto complessa sia);
viene memorizzato in una variabile il tempo (al microsecondo) di termine;
viene mostrata la differenza fra le due variabili.
| scossa's web site |
| Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee.(George Bernard Shaw) |
di ninai data: 09/09/2015 12:30:30
ok
adesso la macro gira
Perciò, se ho capito bene, i tempi di elaborazione non cambiano se i dati esistono o meno e se sono su quel foglio o su un altro.
di scossa data: 09/09/2015 12:59:59
cit. ninai: "i tempi di elaborazione non cambiano se i dati esistono o meno e se sono su quel foglio o su un altro. "
Non capisco cosa intendi.
Se l'ambaradan ti serve per confrontare la velocità di due formule (p.e. Indice+Confronta vs Cerca.Vert) non è che in una metti tutti i riferimenti a celle sullo stesso foglio e nell'altra i dati li hai su file diversi, perché il confronto non avrebbe senso.
In tutto questo il "timer" non ha nessun peso.
| scossa's web site |
| Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee.(George Bernard Shaw) |
di cromagno data: 09/09/2015 18:49:01
Avevo letto qualcosa riguardo "micro timer" ma non ero riuscito a trovare nulla che mi facesse capire bene.
Grazie ancora scossa
di ninai data: 09/09/2015 19:55:01
scossa
tutto ok, non ci fare caso, neanche io capisco cosa intendevo
di perché (utente non iscritto) data: 09/09/2015 20:25:22
Per ulteriori chiarimenti, qui
h t t p ://www.vbaexpress.com/kb/getarticle.php?kb_id=1068
il codice originale ...
di alfrimpa data: 09/09/2015 20:31:36
@ perché
Ho visitato il link che hai postato ma riferimenti a questa discussione non ne ho trovati neanche l'ombra.
Alfredo
di perché (utente non iscritto) data: 09/09/2015 20:39:23
Che vuoi dire?
Io ho solo scritto che quello è il codice "originale" del 2006 della funzione suggerita (MicroTimer) e che c'è un (altro) esempio di utilizzo da studiare. Tutto qui.
Vuoi Approfondire?