Ora c'è un nuovo metodo per misurare i microsecondi in javascript:
http://gent.ilcore.com/2012/06/better-timer-for-javascript.html
Tuttavia, in passato, ho trovato un metodo grezzo per ottenere una precisione di 0,1 millisecondi in JavaScript da un timer di millisecondi. Impossibile? No. Continua a leggere:
Sto eseguendo alcuni esperimenti ad alta precisione che richiedono accuratezze del timer auto-controllate e ho scoperto di essere in grado di ottenere in modo affidabile una precisione di 0,1 millisecondi con alcuni browser su determinati sistemi.
Ho scoperto che nei moderni browser web con accelerazione GPU su sistemi veloci (ad es. I7 quad core, dove diversi core sono inattivi, solo la finestra del browser) - ora posso fidarmi che i timer siano precisi al millisecondo. In effetti, è diventato così preciso su un sistema i7 inattivo che sono stato in grado di ottenere in modo affidabile lo stesso identico millisecondo, in oltre 1.000 tentativi. Solo quando provo a fare cose come caricare una pagina web aggiuntiva o altro, la precisione del millisecondo si riduce (e sono in grado di rilevare con successo la mia precisione degradata eseguendo un controllo temporale prima e dopo, per vedere se il mio tempo di elaborazione si è improvvisamente allungato a 1 o più millisecondi - questo mi aiuta a invalidare i risultati che probabilmente sono stati influenzati troppo negativamente dalle fluttuazioni della CPU).
È diventato così preciso in alcuni browser con accelerazione GPU su sistemi quad-core i7 (quando la finestra del browser è l'unica finestra), che ho scoperto che avrei desiderato poter accedere a un timer di precisione di 0,1 ms in JavaScript, poiché la precisione è finalmente ora su alcuni sistemi di navigazione di fascia alta per rendere utile tale precisione del timer per alcuni tipi di applicazioni di nicchia che richiedono alta precisione e dove le applicazioni sono in grado di autoverificarsi per deviazioni di precisione.
Ovviamente se stai eseguendo più passaggi, puoi semplicemente eseguire più passaggi (es. 10 passaggi) quindi dividere per 10 per ottenere una precisione di 0,1 millisecondi. Questo è un metodo comune per ottenere una migliore precisione: eseguire più passaggi e dividere il tempo totale per il numero di passaggi.
TUTTAVIA ... Se posso eseguire solo un singolo passaggio di benchmark di un test specifico a causa di una situazione insolitamente unica, ho scoperto che posso ottenere una precisione di 0,1 (e talvolta 0,01 ms) in questo modo:
Inizializzazione / Calibrazione:
- Eseguire un ciclo occupato per attendere che il timer passi al millisecondo successivo (allinea il timer all'inizio dell'intervallo di millisecondo successivo) Questo ciclo occupato dura meno di un millisecondo.
- Eseguire un altro ciclo occupato per incrementare un contatore mentre si attende che il timer aumenti. Il contatore ti dice quanti incrementi del contatore si sono verificati in un millisecondo. Questo ciclo occupato dura un millisecondo intero.
- Ripeti quanto sopra, finché i numeri non diventano ultra stabili (tempo di caricamento, compilatore JIT, ecc.). 4. NOTA: La stabilità del numero ti dà la tua precisione raggiungibile su un sistema inattivo. È possibile calcolare la varianza, se è necessario controllare automaticamente la precisione. Le variazioni sono maggiori su alcuni browser e minori su altri browser. Più grande su sistemi più veloci e più lento su sistemi più lenti. Anche la coerenza varia. Puoi dire quali browser sono più coerenti / accurati di altri. Sistemi più lenti e sistemi occupati porteranno a maggiori variazioni tra i passaggi di inizializzazione. In questo modo è possibile visualizzare un messaggio di avviso se il browser non fornisce una precisione sufficiente per consentire misurazioni di 0,1 ms o 0,01 ms. Lo skew del timer può essere un problema, ma alcuni timer interi di millisecondi su alcuni sistemi aumentano abbastanza accuratamente (esattamente sul punto), il che si tradurrà in valori di calibrazione molto coerenti di cui ti puoi fidare.
- Salva il valore del contatore finale (o la media degli ultimi passaggi di calibrazione)
Confronto tra un passaggio e una precisione inferiore al millisecondo:
- Eseguire un ciclo occupato per attendere che il timer passi al millisecondo successivo (allinea il timer all'inizio dell'intervallo di millisecondo successivo). Questo ciclo occupato dura meno di un millisecondo.
- Esegui l'attività che desideri per confrontare con precisione il tempo.
- Controlla il timer. Questo ti dà i millisecondi interi.
- Eseguire un ultimo ciclo occupato per incrementare un contatore mentre si attende che il timer aumenti. Questo ciclo occupato dura meno di un millisecondo.
- Dividere questo valore del contatore per il valore del contatore originale dell'inizializzazione.
- Ora hai la parte decimale dei millisecondi !!!!!!!!
ATTENZIONE: I loop occupati NON sono consigliati nei browser web, ma fortunatamente questi loop occupati vengono eseguiti per meno di 1 millisecondo ciascuno e vengono eseguiti solo poche volte.
Variabili come la compilazione JIT e le fluttuazioni della CPU aggiungono enormi imprecisioni, ma se esegui diversi passaggi di inizializzazione, avrai una ricompilazione dinamica completa e alla fine il contatore si assesta su qualcosa di molto preciso. Assicurati che tutti i loop occupati abbiano esattamente la stessa funzione per tutti i casi, in modo che le differenze nei loop occupati non portino a differenze. Assicurati che tutte le righe di codice vengano eseguite più volte prima di iniziare a fidarti dei risultati, per consentire ai compilatori JIT di essersi già stabilizzati a una ricompilazione dinamica completa (dynarec).
In effetti, ho assistito a una precisione che si avvicinava ai microsecondi su alcuni sistemi, ma non mi fiderei ancora. Ma la precisione di 0,1 millisecondi sembra funzionare in modo abbastanza affidabile, su un sistema quad-core inattivo in cui sono l'unica pagina del browser. Sono arrivato a un caso di test scientifico in cui potevo eseguire solo passaggi una tantum (a causa di variabili univoche che si verificano) e avevo bisogno di cronometrare con precisione ogni passaggio, piuttosto che fare la media di più passaggi ripetuti, quindi è per questo che l'ho fatto.
Ho eseguito diversi pre-passaggi e passaggi fittizi (anche per regolare il dynarec), per verificare l'affidabilità della precisione di 0,1 ms (è rimasto solido per diversi secondi), quindi ho tenuto le mani lontane dalla tastiera / mouse, mentre si verificava il benchmark, quindi ho fatto diversi post-pass per verificare l'affidabilità della precisione di 0,1 ms (è rimasto di nuovo solido). Ciò verifica anche che cose come modifiche dello stato di alimentazione o altre cose non si siano verificate tra il prima e il dopo, interferendo con i risultati. Ripeti il pre-test e il post-test tra ogni singolo passaggio di benchmark. Su questo, ero praticamente certo che i risultati intermedi fossero accurati. Non vi è alcuna garanzia, ovviamente, ma dimostra che in alcuni casi è possibile una precisione <0.1ms in un browser web.
Questo metodo è utile solo in casi molto, molto di nicchia . Anche così, non sarà letteralmente garantito al 100% all'infinito, puoi ottenere un'accuratezza abbastanza affidabile e persino un'accuratezza scientifica se combinata con diversi livelli di verifiche interne ed esterne.