我需要将格式为"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);
Run Code Online (Sandbox Code Playgroud)
而输出是
decoding 172400 start time 121 finish time 244 decoding 172400 start time 236 finish time 383 decoding 172400 start time 116 finish time 416 decoding 172400 start time 235 finish time 421 decoding 172359 start time 149 finish time 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*/)
Run Code Online (Sandbox Code Playgroud)
你有什么建议,最快的方式是什么?请不要问为什么我关心性能,而只是建议如何更快地做到这一点.
结果:
使用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));
Run Code Online (Sandbox Code Playgroud)
此方法不使用任何字符串子字符串或解析方法.它仅使用索引和简单算法:
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';
Run Code Online (Sandbox Code Playgroud)
下一个版本甚至可能更快,因为计算已经部分推算以帮助编译器.因此,阅读和理解起来有点困难:
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;
Run Code Online (Sandbox Code Playgroud)
对于踢,您可能还想看看它是否更快,但我怀疑此代码将与以前的版本相同:
int hour = s[0] * 10 + s[1] - 528;
int minute = s[2] * 10 + s[3] - 528;
int second = s[4] * 10 + s[5] - 528;
Run Code Online (Sandbox Code Playgroud)