3

「HHmmss」形式の文字列をDateTimeまたは整数に高速に変換する必要があります。私はそのようなコードをテストしました:

Console.WriteLine("decoding " + text);
long microseconds = sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L));
Console.WriteLine("start time " + microseconds);
field = DateTime.ParseExact(text, "HHmmss", null);
microseconds = sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L));
Console.WriteLine("finish time " + microseconds);

出力は

172400のデコード
開始時間121
終了時間244

172400のデコード
開始時間236
終了時間383

172400のデコード
開始時間116
終了時間416

172400のデコード
開始時間235
終了時間421

デコード172359
開始時間149
終了時間323

したがって、平均して約150マイクロ秒です。多くの時間ですが、私はHFTソフトウェアを作成しており、最高のHFTの「ティックツートレード」時間は平均10マイクロ秒です(これにはすべてが含まれます)。私はc#を使用することは不可能であることを理解していますが、それでもc#を使用しても150マイクロ秒は多すぎると思います。

今度は別のアルゴリズムを使用したいのですが、テキストから整数を「抽出」する方法がわかりません。

field = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, /*extract hour, min, sec from text*/)

あなたは何を提案できますか、そして何が最速の方法でしょうか?なぜ私がパフォーマンスに関心があるのか​​を尋ねないでください。代わりに、それをより速く行う方法を提案してください。

結果:

DateTime.ParseExact(text, "HHmmss", null)約6〜8ティックを使用

TimeSpan ts = TimeSpan.ParseExact(text, "hhmmss", null);約3〜4ティックを使用

使用int hour = 10 * text[0] + text[1] - 11 * '0';...約0ティック

測定にループを使用する場合、実際には0ティックよりはるかに少なくなります。実際、前回のバージョンは他のバージョンより100倍高速であることがわかりました。

コード:

    long startMicroseconds = sw.ElapsedTicks /*/ (Stopwatch.Frequency / (1000L * 1000L))*/;

    //TimeSpan ts = TimeSpan.ParseExact(text, "hhmmss", null);

    //int hour = 10 * text[0] + text[1] - 11 * '0';
    //int minute = 10 * text[2] + text[3] - 11 * '0';
    //int second = 10 * text[4] + text[5] - 11 * '0';

    field = DateTime.ParseExact(text, "HHmmss", null);

    long finishMicroseconds = sw.ElapsedTicks /*/ (Stopwatch.Frequency / (1000L * 1000L))*/;
    Console.WriteLine("elappsed " + (finishMicroseconds - startMicroseconds));
4

3 に答える 3

9

このアプローチでは、文字列の部分文字列や解析方法は使用しません。インデックスと単純な算術演算のみを使用します。

int hour   = (s[0] - '0') * 10 + s[1] - '0';
int minute = (s[2] - '0') * 10 + s[3] - '0';
int second = (s[4] - '0') * 10 + s[5] - '0';

この次のバージョンは、コンパイラを支援するために計算が部分的に評価されているため、おそらくさらに高速です。その結果、読んで理解するのが少し難しくなります。

int hour   = s[0] * 10 + s[1] - '0' * 11;
int minute = s[2] * 10 + s[3] - '0' * 11;
int second = s[4] * 10 + s[5] - '0' * 11;

キックについては、これがさらに高速かどうかも確認したい場合がありますが、このコードは以前のバージョンと同じになると思います。

int hour   = s[0] * 10 + s[1] - 528;
int minute = s[2] * 10 + s[3] - 528;
int second = s[4] * 10 + s[5] - 528;
于 2012-11-07T13:38:54.913 に答える
3

読みやすさではなくパフォーマンスが本当に必要な場合は、生の文字を直接操作できます。

hour   = 10*s[0] + s[1] - 11*'0';
minute = 10*s[2] + s[3] - 11*'0';
second = 10*s[4] + s[5] - 11*'0';

ところで。DateTime.Now現在の時刻をローカルタイムゾーンに変換する必要があるため、非常に遅いです。DateTime.UtcNow代わりに使用する必要があります。私のコンプDateTime.UtcNowでは9ns、DateTime.Now900nsです。

また、一度だけフェッチする必要がありDateTime.UtcNowます。そうしないと、競合状態になります。

于 2012-11-07T13:39:14.953 に答える
2

これは本当に遅すぎますか?

TimeSpan ts = TimeSpan.ParseExact("172406", "hhmmss", null);
int hh = ts.Hours;
int mm = ts.Minutes;
int ss = ts.Seconds;

少なくとも理解しやすいです。

于 2012-11-07T13:38:01.793 に答える