実行時間をミリ秒単位で取得する必要があります。
私はもともとこの質問を2008年にしていました。それから、受け入れられた答えは new Date()。getTime() を使用することでした。しかし、標準の performance.now() APIを使用するのはしたがって、私はこの答えを受け入れられた答えに変えています。
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.")
NodeJs
:performance
クラスをインポートする必要があります
console.time('someFunction');
someFunction(); // Whatever is timed goes between the two "console.time"
console.timeEnd('someFunction');
注:time()
メソッドとtimeEnd()
メソッドに渡される文字列は一致しなければなりません
(予想どおりに終了するタイマー)の場合
console.time()
のドキュメント:
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);
<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>また、影響を受けるため、anythingにDate
を使用しないでください「システム時間」の変更による。これは、ユーザーが正確なシステム時間を持っていない場合、が無効な結果(「負のタイミング」など)を取得することを意味します。
2014年10月、システムクロックが調子が悪くなり、推測する.... Gmailを開いて、1日のメールをすべて見た「送信済み0分前」。そして、GmailはGoogleの世界クラスのエンジニアによって構築されるはずだと思っていました。.....
(システムクロックを1年前に設定し、Gmailにアクセスして、みんなで大笑いできるようにしましょう。おそらく、JS Date
の- Hall of Shame )
Googleスプレッドシートの now()
関数にもこの問題があります。
Date
を使用するのは、ユーザーhisシステムクロック時間を表示するときだけです。 thetime を取得したり、何かを測定したりする必要はありません。
ローカル開発マシンで関数の実行時間を取得する必要がある場合、ブラウザのプロファイリングツールを使用するか、 などのコンソールコマンドを使用できますconsole.time()
および console.timeEnd()
。
最新のブラウザにはすべて、JavaScriptプロファイラが組み込まれています。これらのプロファイラーは、既存のコードを変更する必要がないため、関数の実行時間に影響を与える可能性があるため、最も正確な測定値を提供する必要があります。
JavaScriptのプロファイルを作成するには:
あるいは、開発マシンで、 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つの重要な点で優れています。
now()
は、ページのナビゲーション開始からのミリ秒数を表すサブミリ秒の解像度を持つdoubleです。マイクロ秒数を小数で返します(たとえば、1000.123の値は1秒と123マイクロ秒です)。
now()
は単調に増加しています。 Date.getTime()
は後続の呼び出しで前方または後方にジャンプできるため、これは重要です。特に、OSのシステム時刻が更新された場合(たとえば、原子時計の同期)、Date.getTime()
も更新されます。 now()
は常に単調に増加することが保証されているため、OSのシステム時間の影響を受けません-常に壁時計時間になります(壁時計がアトミックでないと仮定すると...)。
now()
は、new Date().getTime()
、+ new Date
、およびDate.now()
が存在するほぼすべての場所で使用できます。例外は、Date
とnow()
の時間が混在しないことです。Date
は nix-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 が利用可能です(これは私が書いたものです)。
正確な値を取得するには、 パフォーマンスインターフェース を使用する必要があります。最新バージョンの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の時間の正確さについてもいくつかのリンクを示しています。
Firebugを使用して、コンソールとJavascriptの両方を有効にします。プロファイルをクリックします。リロードしてください。もう一度[プロファイル]をクリックします。レポートを見ます。
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を渡すだけです。
process.hrtime()は、 Node.js内で利用可能です。 - ナノ秒単位で値を返します。
var hrTime = process.hrtime()
console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)
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ページで提供したりするために使用できます。
ここでもadd演算子を使うことができます
var start = +new Date();
callYourFunctionHere();
var end = +new Date();
var time = end - start;
console.log('total execution time = '+ time + 'ms');
変数を1つだけ使用することが可能です。
var timer = -performance.now();
// Do something
timer += performance.now();
console.log("Time: " + (timer/1000).toFixed(5) + " sec.")
timer/1000
- ミリ秒を秒に変換する
.toFixed(5)
- 余分な数字を削除する
それはあなたを助けるかもしれません。
var t0 = date.now(); doSomething(); var t1 = date.now(); console.log("Call to doSomething took approximate" + (t1 - t0)/1000 + " seconds.")
console.time
とperformance.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);
}
}
}
ありがとう、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;
});
これがタイミング関数のデコレータです。
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つのデコレータに同期機能と非同期機能の両方を処理させたい場合は、さらに複雑になります。
数ヶ月前、私は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')
入れ子になっていない複数のものの間の時間を測定したい場合は、これを使用できます。
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'
私の場合は、@文法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"
]
}
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
サーバーとクライアント(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];
}
};
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
パフォーマンス付き
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');
最善の方法はperformance hooks
モジュールを使うことです。不安定ではありますが、コードの特定の領域をmark
し、マークした領域間のmeasure
をduration
にすることができます。
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);
試してみる ここ
この目的を達成するには複数の方法があります。
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');
これが最も効率的な方法です: 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";
+(演算子を追加)または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()は単項演算子+よりも優れたパフォーマンスを発揮します。