【发布时间】:2009-12-03 04:02:57
【问题描述】:
2009-12-04 更新:有关此处发布的一些建议的分析结果,请参见下文!
问题
考虑以下非常无害、非常直接的方法,它使用switch 语句返回定义的枚举值:
public static MarketDataExchange GetMarketDataExchange(string ActivCode) {
if (ActivCode == null) return MarketDataExchange.NONE;
switch (ActivCode) {
case "": return MarketDataExchange.NBBO;
case "A": return MarketDataExchange.AMEX;
case "B": return MarketDataExchange.BSE;
case "BT": return MarketDataExchange.BATS;
case "C": return MarketDataExchange.NSE;
case "MW": return MarketDataExchange.CHX;
case "N": return MarketDataExchange.NYSE;
case "PA": return MarketDataExchange.ARCA;
case "Q": return MarketDataExchange.NASDAQ;
case "QD": return MarketDataExchange.NASDAQ_ADF;
case "W": return MarketDataExchange.CBOE;
case "X": return MarketDataExchange.PHLX;
case "Y": return MarketDataExchange.DIRECTEDGE;
}
return MarketDataExchange.NONE;
}
我和我的同事今天讨论了一些关于如何真正使这种方法更快的想法,我们提出了一些有趣的修改,这些修改实际上确实显着提高了它的性能(当然,按比例来说)。我很想知道其他人能想到哪些我们可能没有想到的优化。
马上,让我提供一个简短的免责声明:这是为了有趣,不是推动整个“优化还是不优化”辩论.也就是说,如果您认为自己属于那些教条主义地相信“过早的优化是万恶之源”的人,请注意我在一家高频交易公司工作,一切都需要绝对运行尽可能快——瓶颈与否。所以,即使我在 SO 上发布这个是为了乐趣,这也不仅仅是浪费时间。
另一个快速说明:我对两种答案感兴趣——那些假设每个输入都是有效的 ActivCode(上面的 switch 语句中的字符串之一),而那些不是。我几乎确信做出第一个假设可以进一步提高速度;无论如何,它为我们做了。但我知道无论哪种方式都可以改进。
结果
嗯,事实证明,迄今为止(我测试过的)最快的解决方案来自 João Angelo,他的建议实际上非常简单,但非常聪明。我和我的同事设计的解决方案(在尝试了几种方法之后,其中许多也是在这里想到的)排在第二位。我正要发布它,但事实证明 Mark Ransom 提出了完全相同的想法,所以请查看他的答案!
自从我运行这些测试后,其他一些用户发布了甚至更新的想法...我会在适当的时候测试它们,当我有更多的空闲时间时。
我在两台不同的机器上运行了这些测试:我家的个人电脑(一台运行 Windows 7 64 位、4 Gb RAM 的双核 Athlon)和我工作的开发机器(一台 2 Gb RAM 的双核 Athlon运行 Windows XP SP3)。显然,时代不同了。但是,相对时间,意思是每种方法与其他方法相比的方式是相同的。也就是说,最快的是两台机器上最快的等等。
现在来看结果。 (我在下面发布的时间来自我的家用电脑。)
但首先,作为参考——原始 switch 语句:
1000000 次运行:98.88 毫秒
平均:0.09888 微秒
迄今为止最快的优化:
João Angelo 的想法是根据 ActivCode 字符串的哈希码为枚举分配值,然后将
ActivCode.GetHashCode()直接封装为MarketDataExchange:
1000000 次运行:23.64 毫秒
平均:0.02364 微秒
速度提升:329.90%我的同事和我将
ActivCode[0]转换为int并从启动时初始化的数组中检索适当的MarketDataExchange的想法(Mark Ransom 提出了完全相同的想法):
1000000 次运行:28.76 毫秒
平均:0.02876 微秒
速度提升:253.13%tster 开启
ActivCode.GetHashCode()输出而不是ActivCode的想法:
1000000 次运行:34.69 毫秒
平均:0.03469 微秒
速度提升:185.04%由包括 Auraseer、tster 和 kyoryu 在内的几位用户提出的想法是打开
ActivCode[0]而不是ActivCode:
1000000 次运行:36.57 毫秒
平均:0.03657 微秒
速度提升:174.66%Loadmaster 使用快速哈希的想法,
ActivCode[0] + ActivCode[1]*0x100:
1000000 次运行:39.53 毫秒
平均:0.03953 微秒
速度提升:153.53%许多人建议使用哈希表 (
Dictionary<string, MarketDataExchange>):
1000000 次运行:88.32 毫秒
平均:0.08832 微秒
速度提升:12.36%使用二分查找:
1000000 次运行:1031 毫秒
平均:1.031 微秒
速度提升:无(性能变差)
我只想说,看到人们对这个简单的问题有多少不同的想法,真是太酷了。这对我来说非常有趣,我非常感谢迄今为止做出贡献和提出建议的每个人。
【问题讨论】:
-
重复 stackoverflow.com/questions/395618/if-else-vs-switch , stackoverflow.com/questions/94305/… , stackoverflow.com/questions/767821/… , stackoverflow.com/questions/1071856/… 等等,所有这些都谈到优化 switch 语句,使用 if/else 以及它如何编译到 IL
-
@Donnie,除了其中一个问题之外,所有问题都在询问是否使用 if/else 或 switch。最后一个是关于如何摆脱 switch 语句。所有这些问题都与这个问题完全不同,这是关于优化特定功能的问题。
-
@Dan,你要发布你所做的……对吧?
-
@不退款不退货:你是对的。我可能不应该说,“这是我们应用程序中最慢的部分,请帮助我们优化它!”我应该说的是我发布这个只是为了好玩,这样人们就可以发布他们的想法并可能学到一些新的和有趣的东西。我也应该把fun这个词加粗,这样没人会错过它......
-
哈哈,好一个丹。这是我参与过的最有趣的 SO 主题。
标签: c# optimization switch-statement