web-dev-qa-db-ja.com

関数が実行するのにかかる時間を測定する方法

実行時間をミリ秒単位で取得する必要があります。

私はもともとこの質問を2008年にしていました。それから、受け入れられた答えは new Date()。getTime() を使用することでした。しかし、標準の performance.now() APIを使用するのはしたがって、私はこの答えを受け入れられた答えに変えています。

934
Julius A

performance.now() を使用します。

var t0 = performance.now();

doSomething();   // <---- The function you're measuring time for 

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

NodeJsperformance クラスをインポートする必要があります


console.timeを使用します。 (非標準)生活水準

console.time('someFunction');

someFunction(); // Whatever is timed goes between the two "console.time"

console.timeEnd('someFunction');


time()メソッドとtimeEnd()メソッドに渡される文字列は一致しなければなりません
予想どおりに終了するタイマー)の場合

console.time()のドキュメント:

  1. に関するNodeJSのドキュメント
  2. MDN(クライアントサイド)ドキュメント
1397
vsync

new Date()を使用してください。getTime()

GetTime()メソッドは、1970年1月1日午前0時からのミリ秒数を返します。

例.

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);
596
Owen

Date()を使用しないでください。以下をお読みください。

performance.now()を使用:

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

動作します:

  • IE 10 ++

  • FireFox 15 ++

  • Chrome 24 ++

  • Safari 8 ++

  • Opera 15 ++

  • Android 4.4 ++

  • などなど

console.timeは実行可能かもしれませんが、非標準です § ​​:

この機能は非標準であり、標準化されていません。 Webに面している本番サイトでは使用しないでください。すべてのユーザーに対して機能するとは限りません。また、実装間で大きな非互換性がある可能性があり、今後動作が変わる可能性があります。

ブラウザーのサポートに加えて、performance.nowにはpotentialがあり、console.timeのベアボーンバージョンのように見えるため、より正確なタイミングを提供します。


<rant>また、影響を受けるため、anythingDateを使用しないでください「システム時間」の変更による。これは、ユーザーが正確なシステム時間を持っていない場合、が無効な結果(「負のタイミング」など)を取得することを意味します。

2014年10月、システムクロックが調子が悪くなり、推測する.... Gmailを開いて、1日のメールをすべて見た「送信済み0分前」。そして、GmailはGoogleの世界クラスのエンジニアによって構築されるはずだと思っていました。.....

(システムクロックを1年前に設定し、Gmailにアクセスして、みんなで大笑いできるようにしましょう。おそらく、JS Dateの-​​ Hall of Shame

Googleスプレッドシートの now() 関数にもこの問題があります。

Dateを使用するのは、ユーザーhisシステムクロック時間を表示するときだけです。 thetime を取得したり、何かを測定したりする必要はありません。

396
Pacerier

ローカル開発マシンで関数の実行時間を取得する必要がある場合、ブラウザのプロファイリングツールを使用するか、 などのコンソールコマンドを使用できますconsole.time() および console.timeEnd()

最新のブラウザにはすべて、JavaScriptプロファイラが組み込まれています。これらのプロファイラーは、既存のコードを変更する必要がないため、関数の実行時間に影響を与える可能性があるため、最も正確な測定値を提供する必要があります。

JavaScriptのプロファイルを作成するには:

  • Chromeで、F12を押して、Profilesタブ、JavaScript CPUプロファイルの収集
  • FirefoxでFirebugをインストール/開き、Profileボタンをクリックします。
  • IE 9 +で、F12を押し、ScriptまたはProfiler(IEのバージョンに応じて)。

あるいは、開発マシンで、 console.time() および console.timeEnd() を使用してコードにインストルメンテーションを追加できます。 Firefox11 +、Chrome2 +、およびIE11 +でサポートされるこれらの関数は、console.time()を介して開始/停止するタイマーについて報告します。 time()はユーザー定義のタイマー名を引数として受け取り、timeEnd()はタイマーが開始されてからの実行時間を報告します。

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

timeEnd()呼び出しで経過時間を返すのはFirefoxのみであることに注意してください。他のブラウザーは、結果を開発者コンソールに報告するだけです。timeEnd()の戻り値は未定義です。

関数の実行時間を野生で取得したい場合、コードをインストルメントする必要があります。いくつかのオプションがあります。 new Date().getTime()を照会することで、開始時間と終了時間を簡単に保存できます。

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

ただし、Dateオブジェクトの解像度はミリ秒のみであり、OSのシステムクロックの変更の影響を受けます。最新のブラウザには、より良いオプションがあります。

より良いオプションは、 高解像度時間 、別名window.performance.now()を使用することです。 now()は、従来のDate.getTime()よりも2つの重要な点で優れています。

  1. now()は、ページのナビゲーション開始からのミリ秒数を表すサブミリ秒の解像度を持つdoubleです。マイクロ秒数を小数で返します(たとえば、1000.123の値は1秒と123マイクロ秒です)。

  2. now()は単調に増加しています。 Date.getTime()は後続の呼び出しで前方または後方にジャンプできるため、これは重要です。特に、OSのシステム時刻が更新された場合(たとえば、原子時計の同期)、Date.getTime()も更新されます。 now()は常に単調に増加することが保証されているため、OSのシステム時間の影響を受けません-常に壁時計時間になります(壁時計がアトミックでないと仮定すると...)。

now()は、new Date().getTime()+ new Date、およびDate.now()が存在するほぼすべての場所で使用できます。例外は、Datenow()の時間が混在しないことです。Datenix-Epoch (1970年からのミリ秒数)に基づいているため、now()は数字ですページナビゲーションが開始されてからミリ秒単位です(したがって、Dateよりはるかに小さくなります)。

now()の使用方法の例を次に示します。

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

now()は、Chrome stable、Firefox 15以降、およびIE10でサポートされています。いくつかの polyfills も利用可能です。

ワイルドで実行時間を測定するためのもう1つのオプションは、 serTimingです。 UserTimingはconsole.time()およびconsole.timeEnd()と同様に動作しますが、now()が使用するのと同じ高解像度タイムスタンプを使用し(したがって、サブミリ秒単調増加クロックを取得します)、タイムスタンプと期間を PerformanceTimeline に保存します。

UserTimingには、marks(timestamps)およびmeasures(duration)の概念があります。どちらでも好きなだけ定義でき、それらは PerformanceTimeline で公開されます。

タイムスタンプを保存するには、mark(startMarkName)を呼び出します。最初のマークからの期間を取得するには、単にmeasure(measurename, startMarkname)を呼び出します。期間は、マークとともにPerformanceTimelineに保存されます。

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

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

UserTimingはIE10 +およびChrome25 +で利用可能です。 polyfill が利用可能です(これは私が書いたものです)。

50
NicJ

正確な値を取得するには、 パフォーマンスインターフェース を使用する必要があります。最新バージョンのFirefox、Chrome、Opera、およびIEでサポートされています。使い方の例を次に示します。

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

Date.getTime()またはconsole.time()は正確な実行時間の測定には適していません。おおまかな概算で問題ない場合は、それらを使用できます。おおよその目安では、リアルタイムから15〜60 msシフトすることができます。

JavaScriptで実行時間を測定するには、この素晴らしい post をチェックしてください。執筆者は、JavaScriptの時間の正確さについてもいくつかのリンクを示しています。

32

Firebugを使用して、コンソールとJavascriptの両方を有効にします。プロファイルをクリックします。リロードしてください。もう一度[プロファイル]をクリックします。レポートを見ます。

18
Stefan Mai
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]');
};

基準

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

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

stopwatch.stop();

stopwatch.printElapsed();

出力

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]

performance.now() はオプションです - StopWatchコンストラクタ関数にfalseを渡すだけです。

11
kayz1

process.hrtime()は、 Node.js内で利用可能です。 - ナノ秒単位で値を返します。

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

NodeJSでtimeEndを値として返す機能を持つようにvsyncのコードをさらに拡張するには、この小さなコードを使用します。

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

今のようにコードを使用します。

console.time('someFunction timer');

someFunction();

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


これはあなたにもっと可能性を与えます。実行時間は、式で使用するなどの目的で使用したり、データベースに保存したり、Webソケットを介してリモートクライアントに送信したり、Webページで提供したりするために使用できます。

8
Levi Roberts

ここでもadd演算子を使うことができます

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

変数を1つだけ使用することが可能です。

var timer = -performance.now();

// Do something

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

timer/1000 - ミリ秒を秒に変換する

.toFixed(5) - 余分な数字を削除する

6
user1032559

それはあなたを助けるかもしれません。

var t0 = date.now(); doSomething(); var t1 = date.now(); console.log("Call to doSomething took approximate" + (t1 - t0)/1000 + " seconds.")

5
Wajeeh Aslam

console.timeperformance.nowはいくつかの主要なブラウザ(すなわちIE10)でサポートされていないので、私は最も利用可能な方法を利用するスリムなユーティリティを作成しました。ただし、誤った使用法(初期化されていないタイマーでEnd()を呼び出す)に対するエラー処理はありません。

それを使用し、あなたが望むようにそれを改善する。

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);
        }
    }
}
5
Mx.

ありがとう、Achim Koellner、あなたの答えを少し広げていきます。

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

注意してください、あなたが測定したいもの以外何もするべきではないことに注意してください(例えば、console.logは実行に時間がかかり、パフォーマンステストに影響するでしょう)。

非同期関数の実行時間を測定するためには、コールバック内にvar timeInMilliseconds = process.hrtime(t0)[1]/1000000;を挿入する必要があります。例えば、

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

});
4
Andrew Marin

これがタイミング関数のデコレータです。

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

使用法:

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' 

あなたが非同期関数を使っているなら、あなたはtimedをasyncにしてf(... args)の前にawaitを追加することができます、そしてそれはそれらのために働くべきです。 1つのデコレータに同期機能と非同期機能の両方を処理させたい場合は、さらに複雑になります。

2
aljgom

数ヶ月前、私はDate.now()を使って関数を計算する独自のルーチンをまとめました - 当時は、受け入れられたメソッドはperformance.now()であるように見えました - パフォーマンスオブジェクトがまだ利用できないためです。安定したNode.jsリリースの-in)。

今日私はもう少し調査をしていて、タイミングのための別の方法を見つけました。 Node.jsコードでこれを使用する方法も見つけたので、ここで共有すると思いました。

以下は、 w3c および 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)
}

注:

Node.jsアプリケーションでperformanceオブジェクトを使用する予定の場合は、次のrequireを含める必要があります。const { performance } = require('perf_hooks')

2

入れ子になっていない複数のものの間の時間を測定したい場合は、これを使用できます。

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

Console.time()と似ていますが、以前のタイマーを追跡する必要がない場合はより簡単に使用できます。

Console.time()の青い色が好きなら、代わりにこの行を使えます

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'
1
aljgom

私の場合は、@文法sugerを使用してbabelでコンパイルすることをおすすめします。
このメソッドの問題は、関数がオブジェクトの中になければならないということです。

サンプル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(6用)

 {
    "plugins": [
        "transform-decorators-legacy"
    ]
 }
1
Yu Huang
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はstringに関連しています。

return Singleton.getInstance().initTime(label); // Returns the time init

return Singleton.getInstance().endTime(label); // Returns the total time between init and end

1
jose920405

累積サイクル付きストップウォッチ

サーバーとクライアント(NodeまたはDOM)で動作し、Performance APIを使用します。あなたは多くの小さなサイクルがあるときに良いです。 1000回呼び出される関数では1000個のデータオブジェクトを処理しますが、この関数の各操作が合計にどのように加算されるかを確認する必要があります。

それで、これはモジュールグローバル(シングルトン)タイマーを使います。クラスシングルトンパターンと同じですが、使用するのは少し簡単ですが、これを別のものに入れる必要があります。 stopwatch.jsファイル。

const perf = typeof performance !== "undefined" ? performance : require('perf_hooks').performance;
const DIGITS = 2;

let _timers = {};

const _log = (label, delta?) => {
    if (_timers[label]) {
        console.log(`${label}: ` + (delta ? `${delta.toFixed(DIGITS)} ms last, ` : '') +
            `${_timers[label].total.toFixed(DIGITS)} ms total, ${_timers[label].cycles} cycles`);
    }
};

export const Stopwatch = {
    start(label) {
        const now = perf.now();
        if (_timers[label]) {
            if (!_timers[label].started) {
                _timers[label].started = now;
            }
        } else {
            _timers[label] = {
                started: now,
                total: 0,
                cycles: 0
            };
        }
    },
    /** Returns total elapsed milliseconds, or null if stopwatch doesn't exist. */
    stop(label, log = false) {
        const now = perf.now();
        if (_timers[label]) {
            let delta;
            if(_timers[label].started) {
                delta = now - _timers[label].started;
                _timers[label].started = null;
                _timers[label].total += delta;
                _timers[label].cycles++;
            }
            log && _log(label, delta);
            return _timers[label].total;
        } else {
            return null;
        }
    },
    /** Logs total time */
    log: _log,
    delete(label) {
        delete _timers[label];
    }
};
1
gombosg
const { performance } = require('perf_hooks');

function addUpTo(n) {
  let total = 0;
  for (let i = 1; i <= n; i++) {
    total += i;
  }
  return total;
}


let t1 = performance.now();
addUpTo(1000000000);
let t2 = performance.now();
console.log(`Time elapsed: ${(t2 - t1) / 1000} seconds`);
// Time elapsed: 1.1261566010713577 seconds
0
Homam Bahrani

パフォーマンス付き

NodeJs:パフォーマンスクラスをインポートする必要があります

var time0 = performance.now(); // Store the time at this point into time0

yourFunction();   // The function you're measuring time for 

var time1 = performance.now(); // Store the time at this point into time1

console.log("youFunction took " + (time1 - time0) + " milliseconds to execute");

Console.timeを使用する

console.time('someFunction');

someFunction(); // Whatever is timed goes between the two "console.time"

console.timeEnd('someFunction');
0
Chandraprakash

最善の方法はperformance hooksモジュールを使うことです。不安定ではありますが、コードの特定の領域をmarkし、マークした領域間のmeasuredurationにすることができます。

const { performance, PerformanceObserver } = require('perf_hooks');

const measures = []

const obs = new PerformanceObserver(list => measures.Push(...list.getEntries()));
obs.observe({ entryTypes: ['measure'] });
const getEntriesByType = cb => cb(measures);

const doSomething = val => {
  performance.mark('beginning of the process');

  val *= 2;

  performance.mark('after multiplication');

  performance.measure('time taken', 'beginning of the process', 'after multiplication');

  getEntriesByType(entries => {
    entries.forEach(entry => console.log(entry));
  })

  return val;
}

doSomething(4);

試してみる ここ

0
toondaey

この目的を達成するには複数の方法があります。

  1. console.timeを使う

    console.time('function'); //run the function in between these two lines for that you need to measure time taken //by the function. ("ex. function();") console.timeEnd('function');

  2. これが最も効率的な方法です: performance.now()を使う

var v1 = performance.now(); //run the function here for which you have top measure the time var v2 = performance.now(); console.log("total time taken = "+(v2-v1)+"milliseconds";

  1. +(演算子を追加)またはgetTime()を使用

    var h2 = +new Date(); //or var h2 = new Date().getTime(); for(i=0;i<500;i++) {//do something} var h3 = +new Date(); //or var h3 = new Date().getTime(); var timeTaken = h3-h2; console.log("time ====", timeTaken);

Dateインスタンスに単項プラス演算子を適用すると、次のようになります。問題のDateインスタンスの値を取得します。それを数値に変換します。

注:getTime()は単項演算子+よりも優れたパフォーマンスを発揮します。

0
Rohit