JavaScript kodunu nasıl karşılaştırabilirim? [kapalı]


106

JavaScript kodunu karşılaştırmama yardımcı olan bir paket var mı? Firebug ve benzeri araçlardan bahsetmiyorum.

Uyguladığım 2 farklı JavaScript işlevini karşılaştırmam gerekiyor. Perl'in Benchmark ( Benchmark.pm ) modülüne çok aşinayım ve JavaScript'te benzer bir şey arıyorum.

JavaScript kodunun karşılaştırılmasına yapılan vurgu abartıldı mı? Fonksiyonların sadece bir turunu zamanlamaktan kurtulabilir miyim?




Bunun kurşun geçirmez olmadığını biliyorum, ama yine de ilgili: bazen sadece bir işlevin yürütmek için harcadığı zamanı nasıl ölçeceğinizi bilmek istersiniz .
Skippy le Grand Gourou

1
İyi bir JavaScript karşılaştırma aracı burada bulabilirsiniz: jsben.ch
EscapeNetscape

Yanıtlar:


36

Her işlevin birkaç yinelemesini zamanlayın. Bir yineleme muhtemelen yeterli olmayacaktır, ancak (işlevlerinizin ne kadar karmaşık olduğuna bağlı olarak) 100 veya hatta 1000 yinelemeye yakın bir yerde bu işi yapmalıdır.

Fonksiyonunuzun hangi bölümlerinin onu yavaşlattığını görmek istiyorsanız Firebug ayrıca bir profilleyiciye de sahiptir .

Düzenleme: Gelecekteki okuyucular için, JSPerf'i öneren aşağıdaki cevap doğru cevap olmalıdır. Benimkini silerdim, ancak OP tarafından seçildiği için yapamıyorum. Kıyaslama yapmak için birçok yineleme yapmaktan çok daha fazlası vardır ve JSPerf bunu sizin için halleder.


12
Basitçe kodunuzun önceden tanımlanmış sayıda yinelemesini zamanlamak kurşun geçirmez değildir . Ayrıca, Firebug'ın açık olması, Firefox'un Just-In-Time (JIT) derleyicisini devre dışı bırakır, bu da testlerin yorumlayıcıda, yani normalde olduğundan çok daha yavaş çalışacağı anlamına gelir. Firebug'ın profil aracını kullanmak size beklediğiniz sonuçları vermez.
Mathias Bynens

1
@Mathias: Dürüst olmak gerekirse, bu cevap gerçekten eski.
Sasha Chedygov

2
Tabii, alınma dostum. Konuyla ilgili daha fazla araştırma yapıldığı için şimdi gelecekte referans olması için yorum yapacağımı düşündüm.
Mathias Bynens

4
Veya jsperf çalışmadığı için jsben.ch kullanın
EscapeNetscape

118

jsperf.com , JS performansını test etmek için gidilecek sitedir. Oradan başlayın. Komut satırından veya komut dosyalarından kendi testlerinizi çalıştırmak için bir çerçeveye ihtiyacınız varsa , jsperf.com'un üzerine inşa edildiği kitaplık olan Benchmark.js'yi kullanın .

Not: Javascript kodunu test eden herkes, "mikro ölçütlerin" (gerçek dünya kod modellerine dayalı daha karmaşık testler yerine belirli bir özelliği veya işlemi hedefleyen küçük testler) tuzakları konusunda kendilerini eğitmelidir. Bu tür testler yararlı olabilir, ancak modern JS çalışma zamanlarının nasıl çalıştığından dolayı yanlışlığa eğilimlidir. Vyacheslav Egorov'un performans ve kıyaslama üzerine sunumu , problemin / problemlerin doğası hakkında bir fikir edinmek için izlemeye değer.

Düzenleme: JSLitmus'uma kaldırılan referanslar artık alakalı veya kullanışlı olmadığı için çalışıyor.


3
Güncelleme: Sadece jsperf.com'u kullanın - çok daha iyi hale geldi ve bu tür şeyler için gerçekten iyi çalışıyor. jslitmus hala çalışıyor, ancak bir süredir aktif olarak geliştirilmedi.
broofa

Bu üstün cevaptır. +1
Justin Force

1
Jsperf kullanmak istedim, ancak N döngüleri için gerçek çağrıyı zamanlamaktan ziyade, bir süre boyunca kodu kaç kez çalıştırabileceğini sayıyor gibi görünüyor. Keşke seçme şansı olsaydı.
Jeach

1
@Jeach - jsperf "işlem / saniye" verir. Bu değeri kodun çalıştırılacağı zamanla (saniye cinsinden) çarpmanız yeterlidir.
broofa

4
Güncelleme: jsperf artık çevrimiçi değil ve ne zaman tekrar çevrimiçi olacağına dair bir haber yok. Daha fazla bilgi için bu github başlığına bakın .
James Gould

74

Karışıma, birinin yararlı bulabileceği hızlı bir zamanlayıcı eklemeniz yeterli:

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

İdeal olarak, bir sınıfa yerleştirilir ve yukarıdaki örnek amaçlar için yaptığım gibi küresel olarak kullanılmaz. Bunu kullanmak oldukça basit olurdu:

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

6
Burada kapakların iyi kullanımı.
Dandy

12
Daha doğru bir sonuç için, developer.mozilla.org/en-US/docs/Web/API/Performance/nowperformance.now()Date()
thormeier

Tam ihtiyacım olan şey - a timeIt ()
Gishu

1
TypeScript sürümü: pastebin.com/gCs9CB5F
Alexander Taylor

1
Node.js için, nanosaniye çözünürlüğü elde etmek için process.hrtime () kullanabilirsiniz.
Xeoncross

57

Sadece basit bir yol.

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

3
Kabul edilen cevap bu olmalıdır. Üçüncü taraf bir hizmeti kullanmak bazen uygun değildir ve yalnızca yerleşik bir özelliği kullanmak mükemmeldir.
brainbag

1
@brainbag - Soru, bir kodun ne kadar uzun süre çalıştığını zamanlamadan daha fazlasını içeren kıyaslama ile ilgiliydi. Ayrıca, konsol zamanlayıcıları yalnızca söz konusu kod 1 milisaniyeden fazla sürerse (çözünürlüklerinin sınırı) yararlıdır.
broofa

Kıyaslamanızı, zamanlayıcı değerine erişim gerektiren bir test paketinde de çalıştırmak isteyebilirsiniz.
JamesDev

20

@Musicfreaks cevabının bu basit uygulamasını kullanıyorum. Hiçbir özellik yok, ancak kullanımı gerçekten çok kolay. Bu bench(function(){return 1/2;}, 10000, [], this)1/2 10,000 defa hesaplayacaktır.

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



1

Basit bir şeye ihtiyacınız varsa, şu şekilde yapabilirsiniz:

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

İşte kodun bir örneği


Benim durumumda kesinlikle en iyi seçenek basitti ... API için yanıt sürelerini karşılaştırmak için bazı testler yazmak (son derece doğru zamanlara gerek yok).
kashiraja
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.