ฉันจะเปรียบเทียบโค้ด JavaScript ได้อย่างไร [ปิด]


104

มีแพ็คเกจที่ช่วยฉันเปรียบเทียบโค้ด JavaScript หรือไม่? ฉันไม่ได้หมายถึง Firebug และเครื่องมือดังกล่าว

ฉันต้องการเปรียบเทียบฟังก์ชัน JavaScript 2 แบบที่ฉันได้ใช้งาน ฉันคุ้นเคยกับโมดูล Benchmark ( Benchmark.pm ) ของ Perl เป็นอย่างดีและฉันกำลังมองหาสิ่งที่คล้ายกันใน JavaScript

การให้ความสำคัญกับการเปรียบเทียบโค้ด JavaScript หายไปหรือไม่ ฉันสามารถใช้เวลาเพียงครั้งเดียวของฟังก์ชันได้หรือไม่?


น่าจะเป็น dup: stackoverflow.com/search?q=javascript+profiler
steamer25


ฉันรู้ว่ามันไม่ได้กันกระสุนและทั้งหมด แต่ที่เกี่ยวข้องอยู่แล้ว: บางครั้งคุณก็ต้องการที่จะรู้วิธีการวัดเวลาที่ถ่ายโดยฟังก์ชั่นในการดำเนินการ
Skippy le Grand Gourou

1
ฉันใช้เครื่องมือเปรียบเทียบ JavaScript ที่ดีได้ที่นี่: jsben.ch
EscapeNetscape

คำตอบ:


36

เพียงแค่เวลาทำซ้ำหลาย ๆ ฟังก์ชั่น การทำซ้ำเพียงครั้งเดียวอาจไม่เพียงพอ แต่ (ขึ้นอยู่กับว่าฟังก์ชันของคุณซับซ้อนเพียงใด) การทำซ้ำที่ใกล้เคียงกับ 100 หรือ 1,000 ครั้งควรจะทำงานได้

Firebug ยังมีตัวสร้างโปรไฟล์หากคุณต้องการดูว่าส่วนใดของฟังก์ชันของคุณทำให้ฟังก์ชันช้าลง

แก้ไข:สำหรับผู้อ่านในอนาคตคำตอบด้านล่างที่แนะนำ JSPerf ควรเป็นคำตอบที่ถูกต้อง ฉันจะลบของฉัน แต่ทำไม่ได้เพราะ OP เลือกแล้ว การเปรียบเทียบมีอะไรมากกว่าการรันการทำซ้ำหลาย ๆ ครั้งและ JSPerf จะดูแลสิ่งนั้นให้คุณ


12
เพียงแค่จับเวลาจำนวนการทำซ้ำที่กำหนดไว้ล่วงหน้าของรหัสของคุณจะไม่สามารถกันกระสุนได้เลย นอกจากนี้การเปิด Firebug จะปิดใช้งานคอมไพเลอร์ Just-In-Time (JIT) ของ Firefox ซึ่งหมายความว่าการทดสอบจะทำงานในล่ามกล่าวคือช้ากว่าที่จะทำอย่างอื่น การใช้โปรไฟล์ของ Firebug จะไม่ให้ผลลัพธ์ที่คุณคาดหวัง
Mathias Bynens

1
@Mathias: เอาล่ะเพื่อความยุติธรรมคำตอบนี้เก่าจริงๆ
Sasha Chedygov

2
แน่นอนว่าไม่มีเพื่อนร่วมกระทำความผิด ฉันคิดว่าฉันจะแสดงความคิดเห็นเพื่อใช้อ้างอิงในอนาคตตอนนี้มีการค้นคว้าเพิ่มเติมเกี่ยวกับเรื่องนี้แล้ว
Mathias Bynens

4
หรือใช้jsben.chเนื่องจาก jsperf หยุดทำงาน
EscapeNetscape

118

jsperf.comคือไซต์ go-to สำหรับทดสอบประสิทธิภาพ JS เริ่มต้นที่นั่น หากคุณต้องการเฟรมเวิร์กสำหรับรันการทดสอบของคุณเองจากบรรทัดคำสั่งหรือสคริปต์ให้ใช้Benchmark.jsไลบรารีที่สร้าง jsperf.com

หมายเหตุ:ใครก็ตามที่ทดสอบโค้ด Javascript ควรให้ความรู้เกี่ยวกับข้อผิดพลาดของ "microbenchmarks" (การทดสอบขนาดเล็กที่กำหนดเป้าหมายคุณลักษณะหรือการดำเนินการเฉพาะแทนที่จะเป็นการทดสอบที่ซับซ้อนมากขึ้นตามรูปแบบโค้ดในโลกแห่งความเป็นจริง) การทดสอบดังกล่าวมีประโยชน์ แต่มีแนวโน้มที่จะไม่ถูกต้องเนื่องจากการทำงานของ JS ที่ทันสมัย การนำเสนอของ Vyacheslav Egorov เกี่ยวกับประสิทธิภาพและการเปรียบเทียบเป็นสิ่งที่ควรค่าแก่การรับชมเพื่อให้รู้สึกถึงลักษณะของปัญหา

แก้ไข:ลบการอ้างอิงไปยัง JSLitmus ของฉันเนื่องจากไม่เกี่ยวข้องหรือเป็นประโยชน์อีกต่อไป


3
อัปเดต: เพียงใช้ jsperf.com - มันดีขึ้นมากและใช้งานได้ดีสำหรับสิ่งนี้ jslitmus ยังคงใช้งานได้ แต่ยังไม่ได้รับการพัฒนาอย่างจริงจังมาระยะหนึ่งแล้ว
broofa

นี่คือคำตอบที่เหนือกว่า +1
Justin Force

1
ฉันต้องการใช้ jsperf แต่ดูเหมือนว่าจะนับจำนวนครั้งที่สามารถรันโค้ดได้ในช่วงเวลาหนึ่งแทนที่จะกำหนดเวลาการเรียกจริงสำหรับ N ลูป ฉันหวังว่าพวกเขาจะมีตัวเลือกให้เลือก
Jeach

1
@Jeach - jsperf ให้ "การดำเนินการ / วินาที" เพียงแค่คูณค่านั้นตามเวลา (เป็นวินาที) ที่รหัสของคุณจะทำงาน
broofa

4
อัปเดต: jsperf ไม่ออนไลน์อีกต่อไปและไม่มีคำว่าจะกลับมาออนไลน์เมื่อใด ดูหัวข้อ github นี้สำหรับข้อมูลเพิ่มเติม
James Gould

74

เพียงแค่เพิ่มตัวจับเวลาอย่างรวดเร็วในการมิกซ์ซึ่งอาจมีประโยชน์:

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

ตามหลักการแล้วมันจะถูกจัดให้อยู่ในชั้นเรียนและไม่ได้ใช้เป็นสากลเหมือนที่ฉันทำเพื่อวัตถุประสงค์ข้างต้น การใช้มันค่อนข้างง่าย:

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

6
ที่นี่ใช้การปิดได้ดี
Dandy

12
เพื่อผลลัพธ์ที่แม่นยำยิ่งขึ้นเราอาจต้องการใช้performance.now()แทนDate() developer.mozilla.org/en-US/docs/Web/API/Performance/now
thormeier

แค่สิ่งที่ฉันต้องการ - a timeIt ()
Gishu

1
เวอร์ชัน TypeScript: pastebin.com/gCs9CB5F
Alexander Taylor

1
สำหรับ node.js คุณสามารถใช้process.hrtime ()เพื่อรับความละเอียดระดับนาโนวินาที
Xeoncross

56

วิธีง่ายๆ

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

3
นี่ควรเป็นคำตอบที่ได้รับการยอมรับ การใช้บริการของบุคคลที่สามบางครั้งก็ไม่สะดวกและเพียงแค่ใช้คุณสมบัติที่เรียบง่ายในตัวเท่านั้น
Brainbag

1
@brainbag - คำถามเกี่ยวกับการเปรียบเทียบซึ่งเกี่ยวข้องกับการกำหนดเวลาว่าโค้ดจะทำงานนานแค่ไหน นอกจากนี้ตัวจับเวลาคอนโซลจะมีประโยชน์ก็ต่อเมื่อโค้ดที่เป็นปัญหาใช้เวลามากกว่า 1 มิลลิวินาที (ขีด จำกัด ของความละเอียด)
broofa

คุณอาจต้องการเรียกใช้เกณฑ์มาตรฐานของคุณในชุดทดสอบซึ่งต้องมีการเข้าถึงค่าตัวจับเวลา
JamesDev

20

ฉันใช้คำตอบ @musicfreaks ที่ใช้งานง่ายนี้ ไม่มีคุณสมบัติใด ๆ แต่ใช้งานง่ายมาก สิ่งนี้bench(function(){return 1/2;}, 10000, [], this)จะคำนวณ 1/2 10,000 ครั้ง

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

มันยากมากที่จะเขียนเกณฑ์มาตรฐานข้ามเบราว์เซอร์ที่ดี เพียงแค่จับเวลาจำนวนการทำซ้ำที่กำหนดไว้ล่วงหน้าของรหัสของคุณจะไม่สามารถกันกระสุนได้เลย

ในฐานะที่เป็น @broofa แนะนำแล้วให้ตรวจสอบjsPerf ใช้Benchmark.jsเบื้องหลัง


2

หากเขียนสคริปต์เปรียบเทียบที่กำหนดเองโปรดทราบว่าเบราว์เซอร์บางตัวใช้การปรับแต่ง dom หลังจากฟังก์ชันที่กำหนดไว้สิ้นสุดลงเท่านั้น รายละเอียดเพิ่มเติมที่นี่ http://www.quirksmode.org/blog/archives/2009/08/when_to_read_ou.html


1

หากคุณต้องการอะไรง่ายๆคุณสามารถทำได้ดังนี้:

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

นี่คือตัวอย่างของรหัส


Simple เป็นตัวเลือกที่ดีที่สุดในกรณีของฉัน ...
kashiraja
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.