Cara mengukur waktu yang dibutuhkan oleh sebuah fungsi untuk mengeksekusi

Saya perlu untuk mendapatkan waktu eksekusi dalam milidetik.

awalnya saya bertanya pertanyaan ini kembali pada tahun 2008. Jawaban yang diterima kemudian gunakan new Date().getTime() Namun, kita semua bisa sepakat sekarang yang menggunakan standar kinerja.sekarang() API lebih tepat. Karena itu saya mengubah diterima jawaban untuk yang satu ini.

Mengomentari pertanyaan (5)
Larutan

Menggunakan [kinerja.sekarang()][1]:


var t0 = performance.now();

doSomething();   // 
Komentar (26)

gunakan new Date().getTime()

getTime() method ini mengembalikan jumlah milidetik sejak tengah malam dari tanggal 1 januari 1970.

ex.

var start = new Date().getTime();

for (i = 0; i < 50000; ++i) {
// do something
}

var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time);
Komentar (14)

Don't menggunakan Date(). Baca di bawah ini.

Gunakan kinerja.sekarang():

<script>
var a = performance.now();
alert('do something...');
var b = performance.now();
alert('It took ' + (b - a) + ' ms.');
</script>

Ia bekerja pada:

  • IE 10 ++

  • FireFox 15 ++

  • Chrome 24 ++

  • Safari 8 ++

  • Opera 15 ++

  • Android 4.4 ++

  • dll, dll

konsol.waktu mungkin layak untuk anda, tapi itu's non-standar &sekte;:

fitur Ini adalah non-standar dan tidak standar trek. Jangan menggunakannya pada tempat produksi menghadap Web: ini tidak akan bekerja untuk setiap pengguna. Ada juga dapat menjadi besar tidak kompatibel antara implementasi dan perilaku dapat berubah di masa depan.

Selain dukungan browser, kinerja.sekarang tampaknya memiliki potensi untuk memberikan yang lebih akurat timing seperti yang muncul untuk menjadi yang telanjang-tulang versi konsol.waktu.


<kata-kata kasar> Juga, DON'T PERNAH menggunakan Upload untuk apapun ** karena itu's terpengaruh oleh perubahan "sistem waktu". Yang berarti kita akan dapatkan tidak valid hasil —seperti "negatif waktu"— ketika pengguna doesn't memiliki sistem yang akurat waktu:

Pada Oktober 2014, saya sistem jam pergi rusak dan menebak apa.... Saya membuka Gmail dan melihat semua hari saya's email "dikirim 0 menit yang lalu". Dan saya'd pikir Gmail seharusnya dibangun oleh teknisi kelas dunia dari Google.......

(Mengatur jam sistem anda untuk satu tahun yang lalu dan pergi ke Gmail sehingga kita semua dapat memiliki tertawa yang baik. Mungkin suatu hari nanti kita akan memiliki Hall of Shame untuk JS Upload.)

Google Spreadsheet's now() fungsi juga menderita dari masalah ini.

Satu-satunya waktu anda'akan menggunakan Tanggal adalah ketika anda ingin menunjukkan pengguna nya sistem waktu jam. Tidak ketika anda ingin mendapatkan the waktu atau untuk mengukur apa-apa.

Komentar (7)

Jika anda perlu untuk mendapatkan fungsi waktu pelaksanaan pada pembangunan lokal mesin, anda dapat menggunakan browser anda's profil yang sesuai, atau konsol perintah seperti konsol.waktu() dan konsol.timeEnd().

Semua browser modern memiliki JavaScript profiler built-in. Ini profiler harus memberikan pengukuran yang paling akurat anda tidak perlu mengubah kode yang ada, yang dapat mempengaruhi fungsi's waktu eksekusi.

Untuk profil anda JavaScript:

  • Di Chrome, tekan F12 dan pilih Profil tab, kemudian Mengumpulkan JavaScript CPU Profil.
  • Di Firefox, install/buka Firebug, dan klik pada Profil tombol.
  • Di IE 9+, tekan F12, klik Naskah atau Profiler (tergantung pada versi IE).

Selain itu, pada mesin pengembangan anda, anda dapat menambahkan instrumentasi untuk kode anda dengan konsol.waktu() dan konsol.timeEnd(). Fungsi-fungsi ini, yang didukung di Firefox11+, Chrome2+ dan IE11+, laporan timer yang anda start/stop melalui konsol.waktu(). time() mengambil sebuah user-defined timer nama sebagai argumen, dan timeEnd() maka laporan pada waktu pelaksanaan sejak waktu dimulai:

function a() {
  console.time("mytimer");
  ... do stuff ...
  var dur = console.timeEnd("myTimer"); // NOTE: dur only works in FF
}

Perhatikan bahwa hanya Firefox kembali waktu yang telah berlalu dalam timeEnd() call. Browser lain hanya melaporkan hasilnya ke konsol pengembang: mengembalikan nilai timeEnd() adalah tidak terdefinisi.

Jika anda ingin mendapatkan fungsi waktu eksekusi liar, anda akan perlu instrumen kode anda. Anda memiliki beberapa pilihan. Anda hanya dapat menyimpan awal dan akhir kali oleh query new Date().getTime():

function a() {
  var start = new Date().getTime();
  ... do stuff ...
  var end = new Date().getTime();
  var dur = end - start;
}

Namun, Tanggal objek hanya memiliki milidetik resolusi dan akan terpengaruh oleh apapun OS's sistem perubahan jam. Di browser modern, ada's merupakan pilihan yang lebih baik.

Pilihan yang lebih baik adalah dengan menggunakan Resolusi Tinggi Waktu, alias jendela.kinerja.now(). now() lebih baik daripada tradisional Tanggal.getTime() dalam dua hal penting:

  1. now() adalah double dengan submillisecond resolusi yang mewakili jumlah milidetik sejak awal halaman's navigasi. Ia mengembalikan jumlah mikrodetik dalam pecahan (misalnya nilai 1000.123 adalah 1 detik dan 123 mikrodetik).

  2. now() adalah monoton meningkat. Hal ini penting sebagai Tanggal.getTime() dapat mungkin melompat maju atau bahkan mundur pada panggilan berikutnya. Terutama, jika OS's waktu sistem diperbarui (misalnya atom clock sinkronisasi), Tanggal.getTime() juga diperbarui. now() dijamin untuk selalu monoton meningkat, sehingga tidak terpengaruh oleh OS's sistem waktu-itu akan selalu menjadi dinding waktu jam (dengan asumsi anda jam dinding bukan atom...).

now() dapat digunakan di hampir setiap tempat yang new Date().getTime(), + Tanggal baru t Tanggal.now() adalah. Pengecualian adalah bahwa Date dan now() times don't campuran, sebagai Tanggal didasarkan pada unix epoch (jumlah milidetik sejak tahun 1970), sementara now() adalah jumlah milidetik sejak navigasi halaman dimulai (sehingga akan jauh lebih kecil dari Tanggal).

Berikut ini's contoh bagaimana menggunakan now():

function a() {
  var start = window.performance.now();
   ... do stuff ...
  var end = window.performance.now();
  var dur = end - start;
}

now() didukung di Chrome stabil, Firefox 15+, dan IE10. Ada juga beberapa polyfills yang tersedia.

Salah satu pilihan lain untuk mengukur waktu eksekusi di alam liar UserTiming. UserTiming berperilaku demikian pula dengan konsol.waktu() dan konsol.timeEnd(), tapi ini menggunakan Resolusi Tinggi yang sama Timestamp yang now() menggunakan (sehingga anda mendapatkan sub-milidetik monotonically increasing jam), dan menghemat waktu dan durasi untuk PerformanceTimeline.

UserTiming memiliki konsep tanda (cap) dan langkah-langkah (durasi). Anda dapat menentukan banyak baik seperti yang anda inginkan, dan mereka're terkena pada PerformanceTimeline.

Untuk menyimpan timestamp, anda menelepon mark(startMarkName). Untuk mendapatkan durasi sejak pertama anda tandai, anda cukup memanggil mengukur(measurename, startMarkname). Durasi ini kemudian disimpan dalam PerformanceTimeline bersama mark.

function a() {
  window.performance.mark("start");
  ... do stuff ...
  window.performance.measure("myfunctionduration", "start");
}

// duration is window.performance.getEntriesByName("myfunctionduration", "measure")[0];

UserTiming tersedia di IE10+ dan Chrome25+. Ada juga polyfill tersedia (yang saya tulis).

Komentar (1)

Untuk mendapatkan nilai-nilai yang tepat, anda harus menggunakan Kinerja interface. It's didukung dalam versi modern dari Firefox, Chrome, Opera dan IE. Berikut ini's contoh bagaimana hal itu dapat digunakan:

var performance = window.performance;
var t0 = performance.now();
doWork();
var t1 = performance.now();
console.log("Call to doWork took " + (t1 - t0) + " milliseconds.")

Saat ini.getTime() atau konsol.waktu() adalah tidak baik untuk mengukur pelaksanaan yang tepat waktu. Anda dapat menggunakannya jika cepat perkiraan kasar adalah OK untuk anda. Dengan perkiraan kasar saya berarti anda bisa mendapatkan 15-60 ms pergeseran dari real time.

Cek brilian ini posting pada pengukuran waktu eksekusi dalam JavaScript. Penulis juga memberikan beberapa link tentang ketepatan waktu JavaScript, layak dibaca.

Komentar (0)

Gunakan Firebug, mengaktifkan kedua Konsol dan Javascript. Klik Profil. Reload. Klik Profil lagi. Melihat laporan.

Komentar (3)
var StopWatch = function (performance) {
    this.startTime = 0;
    this.stopTime = 0;
    this.running = false;
    this.performance = performance === false ? false : !!window.performance;
};

StopWatch.prototype.currentTime = function () {
    return this.performance ? window.performance.now() : new Date().getTime();
};

StopWatch.prototype.start = function () {
    this.startTime = this.currentTime();
    this.running = true;
};

StopWatch.prototype.stop = function () {
    this.stopTime = this.currentTime();
    this.running = false;
};

StopWatch.prototype.getElapsedMilliseconds = function () {
    if (this.running) {
        this.stopTime = this.currentTime();
    }

    return this.stopTime - this.startTime;
};

StopWatch.prototype.getElapsedSeconds = function () {
    return this.getElapsedMilliseconds() / 1000;
};

StopWatch.prototype.printElapsed = function (name) {
    var currentName = name || 'Elapsed:';

    console.log(currentName, '[' + this.getElapsedMilliseconds() + 'ms]', '[' + this.getElapsedSeconds() + 's]');
};

Acuan

var stopwatch = new StopWatch();
stopwatch.start();

for (var index = 0; index < 100; index++) {
    stopwatch.printElapsed('Instance[' + index + ']');
}

stopwatch.stop();

stopwatch.printElapsed();

Output

Instance[0] [0ms] [0s]
Instance[1] [2.999999967869371ms] [0.002999999967869371s]
Instance[2] [2.999999967869371ms] [0.002999999967869371s]
/* ... */
Instance[99] [10.999999998603016ms] [0.010999999998603016s]
Elapsed: [10.999999998603016ms] [0.010999999998603016s]

kinerja.sekarang() adalah opsional - hanya lulus palsu ke StopWatch fungsi constructor.

Komentar (0)

proses.hrtime() tersedia dalam Node.js - mengembalikan nilai dalam nanodetik

var hrTime = process.hrtime()
console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)
Komentar (1)

anda dapat menggunakan add operator juga di sini

 var start = +new Date();
 callYourFunctionHere();
 var end = +new Date();
 var time = end - start;
 console.log('total execution time = '+ time + 'ms');
Komentar (0)

Untuk memperpanjang vsync's kode lebih lanjut untuk memiliki kemampuan untuk mengembalikan timeEnd sebagai nilai dalam NodeJS menggunakan sedikit bagian dari kode.

console.timeEndValue = function(label) { // Add console.timeEndValue, to add a return value
   var time = this._times[label];
   if (!time) {
     throw new Error('No such label: ' + label);
   }
   var duration = Date.now() - time;
   return duration;
};

Sekarang menggunakan kode seperti:

console.time('someFunction timer');

someFunction();

var executionTime = console.timeEndValue('someFunction timer');
console.log("The execution time is " + executionTime);


Ini akan memberi anda lebih banyak kemungkinan. Anda dapat menyimpan waktu eksekusi yang akan digunakan untuk tujuan yang lebih suka menggunakan ini dalam persamaan, atau disimpan dalam database, yang dikirim ke klien jauh lebih websockets, disajikan pada halaman web, dll.

Komentar (0)

Hal ini dimungkinkan untuk hanya menggunakan satu variabel:

var timer = -performance.now();

// Do something

timer += performance.now();
console.log("Time: " + (timer/1000).toFixed(5) + " sec.")

timer/1000 - untuk mengkonversi milidetik untuk detik

.toFixed(5) - untuk memangkas angka tambahan

Komentar (0)

Sejak konsol.waktu dan kinerja.sekarang kan't didukung di beberapa browser utama (yaitu IE10), saya dibuat ramping utilitas yang memanfaatkan metode terbaik yang tersedia. Namun, itu tidak memiliki kesalahan penanganan palsu untuk penggunaan (panggilan End() pada tidak diinisialisasi timer).

Menggunakannya dan meningkatkan seperti yang anda inginkan.

Performance: {
    Timer: {},
    Start: function (name) {
        if (console && console.time) {
            console.time(name);
        } else if (window.performance.now) {
            this.Timer[name] = window.performance.now();
        } else {
            this.Timer[name] = new Date().getTime();
        }
    },
    End: function (name) {
        if (console && console.time) {
            console.timeEnd(name);
        } else {
            var result;
            if (window.performance.now) {
                result = window.performance.now() - this.Timer[name];
            } else {
                result = new Date().getTime() - this.Timer[name];
            }
            console.log(name + ": " + result);
        }
    }
}
Komentar (0)

Hal ini dapat membantu anda.

var t0 = tanggal.sekarang(); melakukan sesuatu(); var t1 = tanggal.sekarang(); konsol.log("Panggilan untuk melakukan sesuatu yang mengambil perkiraan" + (t1 - t0)/1000 + " detik.")

Komentar (1)

Berikut ini's dekorator untuk fungsi-fungsi waktu

let timed = (f) => (...args)=>{
    let start = performance.now();
    let ret = f(...args);
    console.log(`function ${f.name} took ${(performance.now()-start).toFixed(3)}ms`)
    return ret;   
}

Penggunaan:

let test = ()=>{/*does something*/}
test = timed(test)   // turns the function into a timed function in one line
test()               // run your code as normal, logs 'function test took 1001.900ms' 

Jika anda're menggunakan async fungsi anda dapat membuat waktu async dan menambahkan menunggu sebelum f(...args), dan harus bekerja untuk mereka. Hal itu akan lebih rumit jika anda ingin satu dekorator untuk menangani keduanya sinkron dan asinkron fungsi.

Komentar (1)

Terima kasih, Achim Koellner, akan memperluas jawaban anda sedikit:

var t0 = process.hrtime();
//Start of code to measure

//End of code
var timeInMilliseconds = process.hrtime(t0)[1]/1000000; // dividing by 1000000 gives milliseconds from nanoseconds

Harap dicatat, bahwa anda tidak't melakukan apa-apa selain dari apa yang anda inginkan untuk mengukur (misalnya, console.log juga akan mengambil waktu untuk mengeksekusi dan akan mempengaruhi kinerja tes).

Catatan, bahwa dengan mengukur asynchronous fungsi waktu eksekusi, anda harus menyisipkan var timeInMilliseconds = proses.hrtime(t0)[1]/1000000; di dalam callback. Misalnya,

var t0 = process.hrtime();
someAsyncFunction(function(err, results) {
var timeInMilliseconds = process.hrtime(t0)[1]/1000000;

});
Komentar (0)

Beberapa bulan yang lalu saya menempatkan bersama-sama saya sendiri rutin yang kali menggunakan fungsi Date.sekarang() -- meskipun pada saat itu metode yang diterima tampaknya kinerja.sekarang() -- karena kinerja objek yang belum tersedia (built-in) di kandang Node.js rilis.

Hari ini saya melakukan beberapa penelitian lebih lanjut dan menemukan metode lain untuk waktu. Karena saya juga menemukan cara untuk menggunakan ini dalam Node.js kode, saya pikir saya akan berbagi di sini.

Berikut adalah gabungan dari contoh-contoh yang diberikan oleh w3c dan Node.js:

function functionTimer() {
    performance.mark('start')
    functionToBeTimed()
    performance.mark('end')
    performance.measure('Start to End', 'start', 'end')
    const measure = performance.getEntriesByName('Start to End')[0]
    console.log(measure.duration)
}

CATATAN:

Jika anda berniat untuk menggunakan kinerja objek dalam Node.js aplikasi, anda harus meliputi membutuhkan: const { kinerja } = require(&#39;perf_hooks&#39;)

Komentar (1)

Jika anda ingin mengukur waktu antara beberapa hal-hal yang tidak't bersarang anda bisa menggunakan ini:

function timer(lap){ 
    if(lap) console.log(`${lap} in: ${(performance.now()-timer.prev).toFixed(3)}ms`); 
    timer.prev = performance.now();
}

Mirip dengan konsol.waktu(), tapi penggunaan yang lebih mudah jika anda don't perlu untuk melacak sebelumnya timer.

Jika anda suka warna biru dari konsol.waktu(), anda dapat menggunakan baris ini bukan

console.log(`${lap} in: %c${(performance.now()-timer.prev).toFixed(3)}ms`, 'color:blue');
// Usage: 
timer()              // set the start
// do something 
timer('built')       // logs 'built in: 591.815ms'
// do something
timer('copied')      // logs 'copied in: 0.065ms'
// do something
timer('compared')    // logs 'compared in: 36.41ms'
Komentar (0)
export default class Singleton {

  static myInstance: Singleton = null;

  _timers: any = {};

  /**
   * @returns {Singleton}
   */
  static getInstance() {
    if (Singleton.myInstance == null) {
      Singleton.myInstance = new Singleton();
    }

    return this.myInstance;
  }

  initTime(label: string) {
    this._timers[label] = Date.now();
    return this._timers[label];
  }

  endTime(label: string) {
    const endTime = Date.now();
    if (this._timers[label]) {
      const delta = endTime - this._timers[label];
      const finalTime = `${label}: ${delta}ms`;
      delete this._timers[label];
      return finalTime;
    } else {
      return null;
    }
  }
}

InitTime yang terkait dengan string.

kembali Singleton.getInstance().initTime(label); // Mengembalikan waktu init

kembali Singleton.getInstance().endTime(label); // Mengembalikan total waktu antara init dan end

Komentar (0)

Dalam kasus saya, saya perfer untuk menggunakan @ tata bahasa suger dan compile dengan babel. Masalah dari metode ini adalah bahwa fungsi telah berada di dalam objek.

Sampel Kode JS

function timer() {
    return (target, propertyKey, descriptor) => {
        const start = Date.now();
        let oldFunc = descriptor.value;

        descriptor.value = async function (){
            var result = await oldFunc.apply(this, arguments);
            console.log(Date.now() - start);
            return result;
        }
    }
}

// Util function 
function delay(timeout) {
    return new Promise((resolve) => setTimeout(() => {
        resolve();
    }, timeout));
}

class Test {
    @timer()
    async test(timout) {
        await delay(timout)
        console.log("delay 1");
        await delay(timout)
        console.log("delay 2");
    }
}

const t = new Test();
t.test(1000)
t.test(100)

.babelrc (untuk babel 6)

 {
    "plugins": [
        "transform-decorators-legacy"
    ]
 }
Komentar (0)

Stopwatch dengan kumulatif siklus

Bekerja dengan server dan client (Node atau DOM), menggunakan Kinerja API. Baik ketika anda memiliki banyak siklus misalnya dalam sebuah fungsi disebut 1000 kali bahwa proses 1000 data objek tetapi anda ingin melihat bagaimana masing-masing operasi pada fungsi ini menambahkan sampai total.

Jadi yang satu ini menggunakan modul global (singleton) timer. Sama seperti kelas singleton pattern, hanya sedikit lebih sederhana untuk digunakan, tetapi anda perlu untuk menempatkan ini dalam terpisah misal stopwatch.js file.

``javascript const k = typeof kinerja !== "undefined" ? kinerja : require('perf_hooks').kinerja; const DIGIT = 2;

mari _timers = {};

const _log = (label, delta?) => { jika (_timers[label]) { konsol.log(${label}: + (delta ? ${delta.toFixed(DIGIT)} ms lalu, : '') + ${_timers[label].total.toFixed(DIGIT)} ms total, ${_timers[label].siklus} siklus); } };

ekspor const Stopwatch = { mulai(label) { const sekarang = perf.sekarang(); jika (_timers[label]) { jika (!_timers[label].dimulai) { _timers[label].mulai = sekarang; } } else { _timers[label] = { mulai: sekarang, total: 0, siklus: 0 }; } }, /* Kembali total berlalu milidetik, atau null jika stopwatch tidak't ada. / berhenti(label, log = false) { const sekarang = perf.sekarang(); jika (_timers[label]) { mari delta; jika(_timers[label].dimulai) { delta = sekarang - _timers[label].dimulai; _timers[label].mulai = null; _timers[label].total += delta; _timers[label].siklus++; } log && _log(label, delta); kembali _timers[label].total; } else { return null; } }, /* Log total waktu / log: _log, menghapus(label) { menghapus _timers[label]; } }; ``

Komentar (0)