2009-10-13 15 views
24

同僚と私はこの問題について往復しています。提案されたソリューションが良いアイデアであるかどうかについていくつかの外部意見を得たいと考えています。DateTime.Nowの代替案の最適化

最初に、免責条項:「DateTime.Nowを最適化する」という概念は、あなたの一部に狂ったように聞こえることを認識しています。私は先制防御のカップルを持っている:

  1. 私は時々いつも言うそれらの人々は、と思われる「コンピュータが高速です。読みやすさ常には、最適化の前に来る」しかし、多くの場合、どこのパフォーマンスアプリケーションの開発経験から話していますそれは重要かもしれない重要でないかもしれないです。私は可能な限り瞬時に起こることが必要であることを話しています。ナノ秒以内(特定の業種では、となります - 例えばリアルタイム高周波取引)。
  2. これを念頭に置いても、以下で説明する別のアプローチは、実際にはかなり読みやすいです。これは、奇妙なハックではなく、信頼性と高速で動作する単純な方法です。
  3. があります。 DateTime.Nowは、(相対的に言えば)です。以下の方法はです。

今、質問自体に。

基本的に、テストでは、DateTime.Nowは約25ティック(約2.5マイクロ秒)の実行になります。もちろん、これは平均して数千から数百万回の呼び出しになります。最初の呼び出しは実際にはかなりの時間がかかり、その後の呼び出しははるかに高速です。しかし、それでもなお25ティックが平均です。

しかし、私の同僚と私は、DateTime.UtcNowの実行に要する時間が平均でわずか0.03マイクロ秒に短縮されていることに気付きました。以下のためのUTCオフセットを決定する、つまり

public static class FastDateTime { 
    public static TimeSpan LocalUtcOffset { get; private set; } 

    public static DateTime Now { 
     get { return DateTime.UtcNow + LocalUtcOffset; } 
    } 

    static FastDateTime() { 
     LocalUtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now); 
    } 
} 

は夏時間に変更がある一方で、当社のアプリケーションが実行されることはありませんことを考えると、私の提案は、以下のクラスを作成することでした現地時間帯 - 起動時に - その時点から、DateTime.UtcNowの速度を利用して、現在の時刻をより速く得るためには、FastDateTime.Now

アプリケーションが実行されている間(たとえば、アプリケーションが夜間に実行されている場合)にUTCオフセットが変更された場合は、この問題が発生することがありました。私がすでに述べたように、私たちのの場合、それは起こりません。

私の同僚は、これを行う方法については異なるアイデアを持っています。これは私がここで説明するにはあまりにも複雑です。最終的にまで私がと言うことができますが、私たちのアプローチのどちらも正確な結果を返すのですが、私のほうが少し速いです(約0.07マイクロ秒〜0.21マイクロ秒)。私が知りたいのは何

は次のとおりです。

  1. 私はここで何かが足りないのですか?アプリケーションが単一の日付の時間枠内でのみ実行される上記の事実を考えると、FastDateTime.Nowは安全ですか?
  2. 他の誰かがおそらくさらにと思うことがありますか?現在の時間を取得する方法はありますか?逆の順序で答えるために
+2

このような単純化を行う場合、DSTの移行は通常の監視であり、これは問題ではないと既に規定しています。それは、ガードされていない人々を捉えて、1インチも移動することなく、2つのタイムゾーンに自分たち(およびそのアプリケーションソフトウェア)が住んでいることを発見します。あなたのテストスイートがこれをキャッチする唯一の時間は、夏時間の移行中に起こる場合です。まれにしか発生しません(または、テストスイートの一部として嘲笑されます。希少なもの)。 – PaulMcG

答えて

26

DateTime.UtcNowを使用し、データが表示されている現地時間に変換するだけでよいですか?既にDateTime.UtcNowがはるかに高速で、DSTのあいまい性が取り除かれることは既に確認済みです。それぞれUTC対ローカル -

DateTime.Now 

DateTime.UtcNow + LocalUtcOffset 

の結果と

+2

+1 UtcNowのほうがはるかに高速ですが、それは私には驚きでした。 http://blogs.msdn.com/clrperfblog/archive/2009/09/08/computing-time-in-net.aspx – kenny

+2

私は先に進み、ちょうどこの答えを受け入れるでしょう。残念ながら私は変更しなければならないコードの量のためにこれをやっているとは思わない(少なくともまだはない)。しかし、それは信じられないほど論理的な提案です。 –

+0

プレゼンテーションは重要です。現地時間は1つではありませんので、提示されたときにのみ計算することができます。 –

2

2)私は、より高速な方法を考えることはできません。

1)彼らはjust announced for System.IO

を持っているように、パイプライン内の任意のフレームワークの改善が存在する場合、それは安全性について確認するのは難しいですが、それはユニットテストの多くのために泣いている何かチェックする価値があるだろう。夏時間が心に浮かびます。あなたがいない間、システムは明らかに非常に激しく激しくなっています。

7

一つの違いは、Kindプロパティの値です。結果のDateTimeが第三者のライブラリに渡された場合は、返品を検討する

DateTime.SpecifyKind(DateTime.UtcNow + LocalUtcOffset, DateTimeKind.Local) 
4

私はあなたのソリューションが欲しいです。 私はいくつかのテストは、それが通常のDateTime.Now

DateTime.UtcNowと比較してどれだけ速く見るために作られたことはDateTime.UtcNowを使用してDateTime.Now

よりも117倍高速である私たちが継続していない時間自体のみに関心があるならば十分です。 (duration= End_time - Start_timeを実行している)特定のコードセクションの期間を計算するだけであれば、タイムゾーンは重要ではなく、DateTime.UtcNowで十分です。

しかし、我々は時間そのものを必要とするならば、我々は DateTime.UtcNow + LocalUtcOffset

を行うために必要なだけの時間スパンを追加すると、少し が遅くなり、今私のテストによると、私たちは定期的DateTime.Now

よりちょうど49倍高速です

この計算を提案されているように別の関数/クラスに入れると、メソッドを呼び出すと私たちの速度はさらに遅くなります( )。

さらに34倍も高速です!

ところでクラスのメソッドを呼び出すしようとするのではなく、DateTime.UtcNow + LocalUtcOffset : はDateTime.UtcNowを使用要するに

は、私が提案したクラスが インラインコードを使用することで改善することが分かっDateTime.Now

唯一の方法よりもはるかに高速であります[MethodImpl(MethodImplOptions.AggressiveInlining)] を使用してコンパイラがインラインでコンパイルされないようにするためには、高速化していないようです。

関連する問題