Bagaimana cara saya mengukur kode JavaScript? [Tutup]

104

Apakah ada paket yang membantu saya mengukur kode JavaScript? Saya tidak mengacu pada Firebug dan alat semacam itu.

Saya perlu membandingkan 2 fungsi JavaScript berbeda yang telah saya terapkan. Saya sangat akrab dengan modul Perl's Benchmark ( Benchmark.pm ) dan saya mencari sesuatu yang serupa di JavaScript.

Apakah penekanan pada pembandingan kode JavaScript sudah berlebihan? Bisakah saya lolos dengan pengaturan waktu hanya dengan satu kali menjalankan fungsi?

Ionic Walrus
sumber
Kemungkinan duplikat dari Bagaimana Anda menguji kinerja kode JavaScript?
John Slegers
Saya tahu ini bukan antipeluru dan semuanya, tetapi tetap terkait: terkadang Anda hanya ingin tahu bagaimana mengukur waktu yang dibutuhkan oleh suatu fungsi untuk dieksekusi .
Skippy le Grand Gourou
1
Saya alat benchmark JavaScript yang baik dapat Anda temukan di sini: jsben.ch
EscapeNetscape

Jawaban:

36

Cukup waktu beberapa iterasi dari setiap fungsi. Satu iterasi mungkin tidak akan cukup, tetapi (tergantung pada seberapa kompleks fungsi Anda) di suatu tempat yang mendekati 100 atau bahkan 1.000 iterasi harus melakukan pekerjaan itu.

Firebug juga memiliki profiler jika Anda ingin melihat bagian mana dari fungsi Anda yang memperlambatnya.

Sunting: Untuk pembaca selanjutnya, jawaban di bawah ini yang merekomendasikan JSPerf harus menjadi jawaban yang benar. Saya akan menghapus milik saya, tetapi saya tidak bisa karena telah dipilih oleh OP. Ada lebih banyak hal untuk pembandingan daripada hanya menjalankan banyak iterasi, dan JSPerf akan mengurusnya untuk Anda.

Sasha Chedygov
sumber
12
Cukup mengatur waktu sejumlah iterasi yang telah ditentukan sebelumnya dari kode Anda sama sekali tidak antipeluru . Juga, membuka Firebug menonaktifkan kompiler Just-In-Time (JIT) Firefox, yang berarti pengujian akan berjalan di interpreter, yaitu jauh lebih lambat daripada yang seharusnya. Menggunakan profiler Firebug tidak akan memberikan hasil yang Anda harapkan.
Mathias Byn
1
@Mathias: Yah, agar adil, jawaban ini sangat tua.
Sasha Chedygov
2
Tentu, jangan tersinggung sobat. Saya hanya berpikir saya akan berkomentar untuk referensi di masa mendatang setelah lebih banyak penelitian telah dilakukan pada subjek.
Mathias Byn
4
Atau gunakan jsben.ch karena jsperf tidak
aktif
118

jsperf.com adalah situs masuk untuk menguji kinerja JS. Mulailah dari sana. Jika Anda memerlukan kerangka kerja untuk menjalankan pengujian Anda sendiri dari baris perintah atau skrip, gunakan Benchmark.js , pustaka tempat jsperf.com dibuat.

Catatan: Siapa pun yang menguji kode Javascript harus mempelajari perangkap "microbenchmarks" (pengujian kecil yang menargetkan fitur atau operasi tertentu, bukan pengujian yang lebih kompleks berdasarkan pola kode dunia nyata). Pengujian semacam itu dapat berguna tetapi rentan terhadap ketidakakuratan karena cara kerja runtime JS modern. Presentasi Vyacheslav Egorov tentang kinerja dan pembandingan patut ditonton untuk mengetahui sifat masalah.

Sunting: Referensi yang dihapus untuk pekerjaan JSLitmus saya karena tidak lagi relevan atau berguna.

broofa
sumber
3
Pembaruan: Cukup gunakan jsperf.com - ini menjadi jauh lebih baik, dan bekerja sangat baik untuk hal semacam ini. jslitmus masih berfungsi, tetapi belum dikembangkan secara aktif untuk beberapa waktu.
broofa
Ini adalah jawaban terbaik. +1
Justin Force
1
Saya ingin menggunakan jsperf, tetapi tampaknya menghitung berapa kali ia dapat menjalankan kode untuk jangka waktu tertentu, daripada mengatur waktu panggilan sebenarnya untuk N loop. Saya berharap mereka memiliki pilihan untuk dipilih.
Jeach
1
@Jeach - jsperf memberikan "operasi / detik". Kalikan saja nilai itu dengan waktu (dalam detik) kode Anda akan dijalankan.
broofa
4
Pembaruan: jsperf tidak lagi online, dan tidak ada kabar kapan akan kembali online. Lihat utas github ini untuk info lebih lanjut.
James Gould
73

Hanya menambahkan pengatur waktu cepat ke dalam campuran, yang mungkin berguna bagi seseorang:

var timer = function(name) {
    var start = new Date();
    return {
        stop: function() {
            var end  = new Date();
            var time = end.getTime() - start.getTime();
            console.log('Timer:', name, 'finished in', time, 'ms');
        }
    }
};

Idealnya itu akan ditempatkan di kelas, dan tidak digunakan sebagai global seperti yang saya lakukan untuk tujuan contoh di atas. Menggunakannya akan sangat sederhana:

var t = timer('Some label');
// code to benchmark
t.stop(); // prints the time elapsed to the js console
Kenny
sumber
6
Penggunaan penutupan yang baik di sini.
Dandy
12
Untuk hasil yang lebih akurat, seseorang mungkin ingin menggunakan performance.now()daripada Date() developer.mozilla.org/en-US/docs/Web/API/Performance/now
thormeier
Hanya apa yang saya butuhkan - timeIt ()
Gishu
1
Versi TypeScript: pastebin.com/gCs9CB5F
Alexander Taylor
1
Untuk node.js Anda bisa menggunakan process.hrtime () untuk mendapatkan resolusi nanodetik.
Xeoncross
56

Caranya sederhana.

console.time('test');
console.timeEnd('test');
stadnik0ff
sumber
3
Ini harus menjadi jawaban yang diterima. Menggunakan layanan pihak ketiga terkadang tidak nyaman, dan hanya menggunakan fitur bawaan yang sederhana sudah sangat baik.
kantong otak
1
@brainbag - Pertanyaannya adalah tentang pembandingan, yang melibatkan lebih dari sekadar menentukan waktu berapa lama kode berjalan. Selain itu, pengatur waktu konsol hanya berguna jika kode yang dipermasalahkan membutuhkan waktu lebih dari 1 milidetik (batas resolusinya).
broofa
Anda mungkin juga ingin menjalankan tolok ukur Anda dalam rangkaian pengujian, yang memerlukan akses ke nilai timer.
JamesDev
20

Saya telah menggunakan implementasi sederhana dari jawaban @musicfreaks ini. Tidak ada fitur, tetapi sangat mudah digunakan. Ini bench(function(){return 1/2;}, 10000, [], this)akan menghitung 1/2 10.000 kali.

/**
 * Figure out how long it takes for a method to execute.
 * 
 * @param {Function} method to test 
 * @param {number} iterations number of executions.
 * @param {Array} args to pass in. 
 * @param {T} context the context to call the method in.
 * @return {number} the time it took, in milliseconds to execute.
 */
var bench = function (method, iterations, args, context) {

    var time = 0;
    var timer = function (action) {
        var d = Date.now();
        if (time < 1 || action === 'start') {
            time = d;
            return 0;
        } else if (action === 'stop') {
            var t = d - time;
            time = 0;    
            return t;
        } else {
            return d - time;    
        }
    };

    var result = [];
    var i = 0;
    timer('start');
    while (i < iterations) {
        result.push(method.apply(context, args));
        i++;
    }

    var execTime = timer('stop');

    if ( typeof console === "object") {
        console.log("Mean execution time was: ", execTime / iterations);
        console.log("Sum execution time was: ", execTime);
        console.log("Result of the method call was:", result[0]);
    }

    return execTime;  
};
fncomp
sumber
9

Sangat sulit untuk menulis tolok ukur lintas-browser yang layak. Cukup mengatur waktu sejumlah iterasi yang telah ditentukan sebelumnya dari kode Anda sama sekali tidak antipeluru .

Seperti yang sudah disarankan oleh @broofa, lihat jsPerf . Ini menggunakan Benchmark.js di belakang layar.

Mathias Bynens
sumber
1

Jika Anda membutuhkan sesuatu yang sederhana, Anda dapat melakukannya seperti ini:

'use strict'
console.clear()

const powerOf = x => y => Math.pow(x, y)
const powerOfThree = powerOf(3)

function performanceCalc(fn, ...params) {
    const start = +new Date()
    const result = fn(...params)
    const end = +new Date()

    console.log(`Result: ${result}. Execution Time: ${end - start} ms`)
}

performanceCalc(powerOfThree, 2)

Berikut adalah contoh kodenya

Vlad Bezden
sumber
Sederhana jelas merupakan pilihan terbaik dalam kasus saya ... menulis beberapa tes untuk mengukur waktu respons untuk API (tidak perlu waktu yang sangat akurat).
kashiraja