JavaScriptでミリ秒単位で時間を取得するより良い方法は?


141

この値を取得する必要があるたびに新しいオブジェクトをインスタンス化する必要なく、日付オブジェクトを使用してミリ秒単位で時間を取得する代替手段、または少なくともそのオブジェクトを再利用する方法はありますか?JavaScriptで単純なゲームエンジンを作成しようとしているため、これを求めています。「デルタフレーム時間」を計算するときは、フレームごとに新しいDateオブジェクトを作成する必要があります。これによるパフォーマンスへの影響についてはあまり心配していませんが、このオブジェクトによって返される正確な時刻の信頼性に問題があります。

毎秒ぐらいアニメーションで奇妙な「ジャンプ」が発生します。これがJavaScriptのガベージコレクションに関連しているか、更新が非常に速い場合のDateオブジェクトの制限に関連しているかはわかりません。デルタ値を一定に設定すると、アニメーションが完全にスムーズになるため、この「ジャンプ」が時間の取得方法に関連していると確信しています。

私が与えることができる唯一の関連コードは、デルタ時間を計算する方法です:

prevTime = curTime;
curTime = (new Date()).getTime();
deltaTime = curTime - prevTime;

動き/アニメーションを計算するとき、私は一定の値にデルタ時間を掛けます。

Dateオブジェクトを使用して時間をミリ秒単位で取得するのを回避する方法がない場合、変数をインクリメントする関数(ゲーム開始からの経過時間はミリ秒単位)となり、SetTimer関数を使用して次のレートで呼び出されますミリ秒に1回は効率的で信頼性の高い代替手段ですか?

編集:さまざまなブラウザでコードをテストしましたが、この「ジャンプ」は実際にはFirefoxではなくChromeでのみ確認できるようです。しかし、両方のブラウザで機能するメソッドがあればなお良いでしょう。


5
フレームごとに1つのオブジェクトは何もない
CodesInChaos

2
1秒ごとにジャンプするアニメーションについて、これはDate.getMilliseconds現在の秒のミリ秒(0〜999)のみを返すという事実と関係がありますか?あなたの例ではこの関数を使用していませんが、おそらく他の場所で使用されているのでしょうか、それとも別のブランチで使用されているのでしょうか?
Dan Ross

2
ジャンプはいくつかの奇妙なミリ秒の解像度の問題に関連していますか?Mozillaのドキュメントから:「タイムスタンプまたは一意のIDを作成するためにnow()を使用する場合、Windowsでは解像度が15ミリ秒になる場合があることに注意してください」。それはしゃっくりに関連しているのでしょうか?
zashu 2013年

1
@zashuこれはずっと前のことなので、この例の詳細を覚えていません。しかし、より最近のアプリケーションでは、Date.now()を使用すると、ジャンプすることがなくなります。
Colin Dumitru 2013年

回答:


173

Date.now()を試してください。

スキップは、おそらくガベージコレクションが原因です。通常、ガベージコレクションは変数を可能な限り再利用することで回避できますが、ガベージコレクションの一時停止を減らすために使用できるメソッドを具体的に述べることはできません。


1
Date.now()を使用してみましたが、同じジャンプがまだあります。ですから、ガベージコレクションの問題ではなく、Dateオブジェクトで正確な値を取得する際の制限ではないことを確信しています。私が言ったように、デルタ時間を定数値で置き換えると、アニメーション/遷移がスムーズになるため、発生する可能性のあるガベージコレクションは、「new Date」または「Date.now()」のみです(この関数が独自のオブジェクトである場合、私は知りません)。
Colin Dumitru

22
正解です:これはIE8以下では機能しません
Nick

1
私はします:/私が欲しいのはミリ秒単位の日付です。必要なもののためにとても複雑に思えます。
ダミアンゴールディング2014

5
@Prozi 1 .. IEイムウェブはIE、ちょうどChromeとFirefoxについて私は本当にいけないケアをプログラミングするとき、本当に......、吸う
TechLife

3
@TechLifeまた、Android、Safari、およびオペラのブラウザーに一線を画す必要がありますが、IEは大量のゴミであることに同意します。私はそれはMSはあきらめたとW10に新しいブラウザを実装していることをとても残念だ意味
Dendromaniac

49

私はこれがかなり古いスレッドであることを知っていますが、物事を最新かつより関連性のあるものに保つために、より正確なperformance.now()機能を使用してJavaScriptでより細かいタイミングを取得できます。

window.performance = window.performance || {};
performance.now = (function() {
    return performance.now       ||
        performance.mozNow    ||
        performance.msNow     ||
        performance.oNow      ||
        performance.webkitNow ||            
        Date.now  /*none found - fallback to browser default */
})();

2
最後の選択肢はDate.now、匿名関数式の代わりにすべきです
Bergi

1
残念ながら、愚かな古いブラウザでも動作しません。幸運にも、IE7とIE8のサポートに費やした時間を支払うようにクライアントに納得してもらいました。
Michael Scheper

2
|| function(){return new Date()。getTime()}
mmm

2
performance.now()からの時間とは異なり、単調な時間を与えることに注意してくださいDate。これは、後続のすべての呼び出しが、前の呼び出し以上の値を返すことが保証されていることを意味します。
ユーザー

48

私が知る限り、あなたは日付でしか時間を得ることができません。

Date.nowが解決策ですが、どこでも利用できるわけではありません:https : //developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/now

var currentTime = +new Date();

これにより、現在の時間がミリ秒単位で表示されます。

あなたのジャンプのためにデルタフレーム時間に従って補間を正しく計算し、丸め誤差がない場合は、ガベージコレクター(GC)に賭けます。

ループ内に作成された一時オブジェクトがたくさんある場合、ガベージコレクションはスレッドをロックして、クリーンアップとメモリの再編成を行う必要があります。

Chromeでは、GCが費やしている時間をタイムラインパネルで確認できます。

編集:私の答え以来、Date.now()それはどこでもIE> = 9でサポートされているので、最良のオプションと見なされるべきです


4
+サーブはどのような機能+newですか?
Andrew Scagnelli 2012年

33
+単にキャストDateNumberミリ秒単位の標準的なUNIXタイムスタンプを与え、。この値を明示的に取得するには、(new Date()).getTime()
ngryman

9
@mikenelson:私にとって恐ろしいことではありません、これは強制がどのように機能するかを知っているときに明白ですDate.now()
ngryman 2013

1
私は好む+よりも.getTime()...それは簡単ですし、私は関数名を覚える必要はありません

2
@TravisJ素晴らしいショートカット?オブジェクトを作成するコンピューター内に既にある数値を取得するには、intをテストし、関数(valueOf)を呼び出す変換をトリガーする演算子を呼び出し、最後に関数(getTime)を呼び出すクラス変換メソッドを呼び出します値を取得します。その後、オブジェクトはその運命に放棄され、ループの1000回の反復の後、ガベージコレクションが必要な1000個のDateオブジェクトが削除され、突然すべてが一緒にダンプされます。コンピューターが遅れている間に、何が起こっているのか疑問に思います。:) 驚くばかり!
FrancescoMM

7

次のような日付オブジェクトがある場合

var date = new Date('2017/12/03');

次に、valueOf()であるミリ秒形式で日付を取得するためのJavaScriptに組み込みメソッドがあります

date.valueOf(); //1512239400000 in milliseconds format

2

これは非常に古い質問ですが、他の人が見ている場合でも参照できるrequestAnimationFrame()ように、最新のブラウザでアニメーションを処理する正しい方法です。

更新:mozillaリンクはこれを行う方法を示しています-リンクの背後にあるテキストを繰り返す気になりませんでした;)


4
Stack Overflowへようこそ!requestAnimationFrame質問で説明されているように、この「ジャンプ」を停止させるものの簡単な説明を含めることができます。ありがとう!
カンタス94ヘビー

2
requestAnimationFrameを使用しても、フレームレートがすべてのプラットフォームで同じであると想定する必要はないため、現在の時刻を確認する必要があります。
トムBoutell 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.