Làm cách nào để tôi có thể chuẩn mã JavaScript? [đóng cửa]


104

Có gói nào giúp tôi chuẩn mã JavaScript không? Tôi không đề cập đến Firebug và các công cụ như vậy.

Tôi cần so sánh 2 hàm JavaScript khác nhau mà tôi đã triển khai. Tôi rất quen thuộc với mô-đun Điểm chuẩn ( Benchmark.pm ) của Perl và tôi đang tìm kiếm thứ gì đó tương tự trong JavaScript.

Có phải sự nhấn mạnh vào mã JavaScript đánh giá điểm chuẩn không? Tôi có thể xử lý thời gian chỉ với một lần chạy các chức năng không?


Có vẻ là một sự
trùng lặp


Tôi biết nó không chống đạn và tất cả, nhưng dù sao cũng có liên quan: đôi khi bạn chỉ muốn biết cách đo thời gian mà một hàm thực thi .
Skippy le Grand Gourou

1
Tôi tốt JavaScript công cụ benchmark bạn có thể tìm thấy ở đây: jsben.ch
EscapeNetscape

Câu trả lời:


36

Chỉ cần thời gian lặp lại một số chức năng. Một lần lặp có thể là không đủ, nhưng (tùy thuộc vào mức độ phức tạp của các hàm của bạn) ở đâu đó gần 100 hoặc thậm chí 1.000 lần lặp sẽ thực hiện công việc.

Firebug cũng có một trình mô tả nếu bạn muốn xem phần nào trong chức năng của mình đang làm chậm nó.

Chỉnh sửa: Đối với độc giả trong tương lai, câu trả lời dưới đây đề xuất JSPerf nên là câu trả lời chính xác. Tôi muốn xóa của tôi, nhưng tôi không thể vì nó đã được OP chọn. Còn nhiều hơn thế nữa để đo điểm chuẩn ngoài việc chỉ chạy nhiều lần lặp lại và JSPerf sẽ giải quyết điều đó cho bạn.


12
Đơn giản chỉ định thời gian cho một số lần lặp lại mã được xác định trước là hoàn toàn không hiệu quả . Ngoài ra, việc mở Firebug sẽ vô hiệu hóa trình biên dịch Just-In-Time (JIT) của Firefox, có nghĩa là các bài kiểm tra sẽ chạy trong trình thông dịch, tức là chậm hơn nhiều so với cách khác. Sử dụng hồ sơ của Firebug sẽ không mang lại cho bạn kết quả như mong đợi.
Mathias Bynens

1
@Mathias: Chà, công bằng mà nói, câu trả lời này thực sự cũ.
Sasha Chedygov

2
Chắc chắn, không có người bạn đời xúc phạm. Tôi chỉ nghĩ rằng tôi sẽ bình luận để tham khảo trong tương lai vì bây giờ nhiều nghiên cứu hơn đã được thực hiện về chủ đề này.
Mathias Bynens,

4
Hoặc sử dụng jsben.ch vì jsperf không hoạt động
EscapeNetscape

118

jsperf.com là trang web truy cập để kiểm tra hiệu suất JS. Bắt đầu từ đó. Nếu bạn cần một khuôn khổ để chạy các bài kiểm tra của riêng mình từ dòng lệnh hoặc tập lệnh, hãy sử dụng Benchmark.js , thư viện mà jsperf.com được xây dựng.

Lưu ý: Bất kỳ ai thử nghiệm mã Javascript nên tự tìm hiểu về các cạm bẫy của "microbenchmarks" (các thử nghiệm nhỏ nhắm mục tiêu đến một tính năng hoặc hoạt động cụ thể, thay vì các thử nghiệm phức tạp hơn dựa trên các mẫu mã trong thế giới thực). Các bài kiểm tra như vậy có thể hữu ích nhưng dễ bị thiếu chính xác do cách hoạt động của thời gian chạy JS hiện đại. Phần trình bày của Vyacheslav Egorov về hiệu suất và điểm chuẩn rất đáng xem để cảm nhận bản chất của (các) vấn đề.

Chỉnh sửa: Đã xóa các tham chiếu đến JSLitmus của tôi hoạt động vì nó không còn phù hợp hoặc hữu ích nữa.


3
Cập nhật: Chỉ cần sử dụng jsperf.com - nó đã tốt hơn rất nhiều và hoạt động thực sự tốt cho loại thứ này. jslitmus vẫn hoạt động, nhưng đã không được phát triển tích cực trong một thời gian khá dài.
broofa

Đây là câu trả lời vượt trội. +1
Justin Force

1
Tôi muốn sử dụng jsperf, nhưng có vẻ như nó đang đếm số lần nó có thể chạy mã trong một khoảng thời gian, thay vì tính thời gian cuộc gọi thực tế cho N vòng lặp. Tôi ước họ có một tùy chọn để lựa chọn.
Jeach

1
@Jeach - jsperf cung cấp "các phép toán / giây". Chỉ cần nhân giá trị đó với thời gian (tính bằng giây) mà mã sẽ chạy.
broofa 21/12/13

4
Cập nhật: jsperf không còn trực tuyến nữa và không có thông tin nào về thời điểm trực tuyến trở lại. Xem chuỗi github này để biết thêm thông tin.
James Gould

73

Chỉ cần thêm bộ hẹn giờ nhanh vào danh sách kết hợp, ai đó có thể thấy hữu ích:

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');
        }
    }
};

Lý tưởng nhất là nó sẽ được đặt trong một lớp, và không được sử dụng như một toàn cục như tôi đã làm cho các mục đích ví dụ ở trên. Sử dụng nó sẽ khá đơn giản:

var t = timer('Some label');
// code to benchmark
t.stop(); // prints the time elapsed to the js console

6
Sử dụng tốt các đóng cửa ở đây.
Dandy

12
Để có kết quả chính xác hơn, người ta có thể muốn sử dụng performance.now()thay vì Date() developer.mozilla.org/en-US/docs/Web/API/Performance/now
thormeier

Chỉ những gì tôi cần - một thời gianIt ()
Gishu

1
Phiên bản TypeScript: pastebin.com/gCs9CB5F
Alexander Taylor

1
Đối với node.js, bạn có thể sử dụng process.hrtime () để có độ phân giải nano giây.
Xeoncross

56

Chỉ cách đơn giản.

console.time('test');
console.timeEnd('test');

3
Đây phải là câu trả lời được chấp nhận. Việc sử dụng dịch vụ của bên thứ ba đôi khi không thuận tiện và chỉ cần sử dụng một tính năng đơn giản được tích hợp sẵn là bạn đã có thể hoàn thành xuất sắc.
brainbag

1
@brainbag - Câu hỏi là về điểm chuẩn, không chỉ đơn giản là tính thời gian mà một đoạn mã chạy trong bao lâu. Ngoài ra, bộ hẹn giờ trên bảng điều khiển chỉ hữu ích nếu mã được đề cập mất hơn 1 mili giây (giới hạn độ phân giải của chúng).
broofa

Bạn cũng có thể muốn chạy điểm chuẩn của mình trong bộ thử nghiệm, bộ thử nghiệm yêu cầu có quyền truy cập vào giá trị bộ đếm thời gian.
JamesDev

20

Tôi đã sử dụng triển khai đơn giản này của câu trả lời @musicfreaks. Không có tính năng nào, nhưng nó thực sự dễ sử dụng. Điều này bench(function(){return 1/2;}, 10000, [], this)sẽ tính 1/2 10.000 lần.

/**
 * 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;  
};

9

Thực sự rất khó để viết các điểm chuẩn trên nhiều trình duyệt. Đơn giản chỉ định thời gian cho một số lần lặp lại mã được xác định trước là hoàn toàn không hiệu quả .

Như @broofa đã đề xuất, hãy xem jsPerf . Nó sử dụng Benchmark.js đằng sau hậu trường.



1

Nếu bạn cần một cái gì đó đơn giản, bạn có thể làm như sau:

'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)

Đây là một ví dụ về mã


Đơn giản chắc chắn là lựa chọn tốt nhất trong trường hợp của tôi ... viết một số thử nghiệm để đánh giá thời gian phản hồi cho API (không cần thời gian cực kỳ chính xác).
kashiraja
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.