你将如何让这个switch语句尽可能快? [英] How would you make this switch statement as fast as possible?

查看:145
本文介绍了你将如何让这个switch语句尽可能快?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

2009-12-04更新:关于一些张贴在这里的建议分析结果,见下文

2009-12-04 UPDATE: For profiling results on a number of the suggestions posted here, see below!


考虑下面很无害的,非常简单的方法,它采用了开关语句返回定义枚举值:

Consider the following very harmless, very straightforward method, which uses a switch statement to return a defined enum value:

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;
}



我和我的同事今天周围的一些想法击了有关如何真正使这方法更快,我们想出了其实并提高其性能,而显著(按比例来说,当然)一些有趣的改变。我很想知道在那里能想到什么样的优化别人的了,可能不会发生给我们。

My colleague and I batted around a few ideas today about how to actually make this method faster, and we came up with some interesting modifications that did in fact improve its performance rather significantly (proportionally speaking, of course). I'd be interested to know what sorts of optimizations anyone else out there can think up that might not have occurred to us.

马上蝙蝠,我只想提供一个快速免责声明:这是对的乐趣的燃料整个优化或不优化的争论。也就是说,如果你那些谁教条地认为算作自己不成熟的优化是一切罪恶的根源,要知道,我对高频交易公司,其中的所有的需要绝对的运行工作尽可能快 - 瓶颈或没有。所以,尽管我张贴这对所以的乐趣,它不只是时间了巨大的浪费,无论是。

Right off the bat, let me just offer a quick disclaimer: this is for fun, and not to fuel the whole "to optimize or not to optimize" debate. That said, if you count yourself among those who dogmatically believe "premature optimization is the root of all evil," just be aware that I work for a high-frequency trading firm, where everything needs to run absolutely as fast as possible--bottleneck or not. So, even though I'm posting this on SO for fun, it isn't just a huge waste of time, either.

一更快速注:我感兴趣2种答案 - 那些假设每个输入将是一个有效的ActivCode(在开关上方语句的字符串之一)和那些没有。我的几乎的肯定,使得第一个假设允许进一步加快改善;无论如何,它为我们做了。但我知道,改进是可能的两种方式。

One more quick note: I'm interested in two kinds of answers--those that assume every input will be a valid ActivCode (one of the strings in the switch statement above), and those that do not. I am almost certain that making the first assumption allows for further speed improvements; anyway, it did for us. But I know that improvements are possible either way.


好了,事实证明,最快的解决方案至今(我已经测试过)从若昂天使,他的建议是,其实很简单,但非常聪明的来了。 (其中许多被认为在这里也尝试了多种方法后,)我的同事和我都想出解决的办法排在第二位;我打算将它张贴,但事实证明,马克赎金想出了相同的想法,所以只检查了他的答案!

Well, it turns out that the fastest solution so far (that I've tested) came from João Angelo, whose suggestion was actually very simple, yet extremely clever. The solution that my coworker and I had devised (after trying out several approaches, many of which were thought up here as well) came in second place; I was going to post it, but it turns out that Mark Ransom came up with the exact same idea, so just check out his answer!

既然我跑这些测试,其他一些用户已经发布甚至的的想法......我会在适当的时候对其进行测试,当我有一个几分钟不遗余力。

Since I ran these tests, some other users have posted even newer ideas... I will test them in due time, when I have a few more minutes to spare.

我跑了两个不同计算机上这些测试:在家里我的个人电脑(双核速龙与4 GB RAM运行Windows 7 64位)和我的开发机在工作(双核速龙与2 GB RAM运行Windows XP SP3)。显然,时间分别不同;然而,在相对的时间,这意味着,每个方法如何相比每隔一个方法,是相同的。也就是说,最快是最快的在两台机器等

I ran these tests on two different machines: my personal computer at home (a dual-core Athlon with 4 Gb RAM running Windows 7 64-bit) and my development machine at work (a dual-core Athlon with 2 Gb RAM running Windows XP SP3). Obviously, the times were different; however, the relative times, meaning, how each method compared to every other method, were the same. That is to say, the fastest was the fastest on both machines, etc.

现在的结果。 (我下面张贴的时间是从我家的电脑。)

Now for the results. (The times I'm posting below are from my home computer.)

但是,首先,以供参考 - 原switch语句:结果
百万运行:98.88毫秒结果
平均:0.09888微秒

But first, for reference--the original switch statement:
1000000 runs: 98.88 ms
Average: 0.09888 microsecond

最快优化迄今:


  1. 赋值的基础上的ActivCode字符串的哈希码的枚举,然后直接套管的若昂·安杰洛的想法 ActivCode.GetHashCode() MarketDataExchange :结果
    百万运行:23.64毫秒结果
    平均:0.02364微秒结果
    速度增长:329.90 %

  1. João Angelo's idea of assigning values to the enums based on the hash codes of the ActivCode strings and then directly casing ActivCode.GetHashCode() to MarketDataExchange:
    1000000 runs: 23.64 ms
    Average: 0.02364 microsecond
    Speed increase: 329.90%

我的同事的和一个 ActivCode [0] 理念> INT 和获取适当的 MarketDataExchange 从启动时初始化数组(这完全一样的想法是由马克赎金建议):结果
百万运行:28.76毫秒结果
平均:0.02876微秒结果
速度增长:253.13%

My colleague's and my idea of casting ActivCode[0] to an int and retrieving the appropriate MarketDataExchange from an array initialized on startup (this exact same idea was suggested by Mark Ransom):
1000000 runs: 28.76 ms
Average: 0.02876 microsecond
Speed increase: 253.13%

tster的想法对输出切换 ActivCode.GetHashCode()而不是 ActivCode :结果
百万运行:34.69毫秒结果
平均:0.03469微秒结果
速度增长:185.04%

tster's idea of switching on the output of ActivCode.GetHashCode() instead of ActivCode:
1000000 runs: 34.69 ms
Average: 0.03469 microsecond
Speed increase: 185.04%

的想法,由几个建议用户包括接通 ActivCode [0] 而不是 ActivCode Auraseer,tster,和恐龙,:结果
百万运行:36.57毫秒结果
平均:0.03657微秒结果
速度增长:174.66%

The idea, suggested by several users including Auraseer, tster, and kyoryu, of switching on ActivCode[0] instead of ActivCode:
1000000 runs: 36.57 ms
Average: 0.03657 microsecond
Speed increase: 174.66%

装卸长的使用快速散的想法, ActivCode [0] + ActivCode [1] *为0x100 :结果
百万运行:39.53毫秒结果
平均:0.03953微秒结果
速度增长:153.53%

Loadmaster's idea of using the fast hash, ActivCode[0] + ActivCode[1]*0x100:
1000000 runs: 39.53 ms
Average: 0.03953 microsecond
Speed increase: 153.53%

使用哈希表(词典<字符串,MarketDataExchange> ; ),被许多建议:结果
百万运行:88.32毫秒结果
平均:0.08832微秒结果
速度增长:12.36%

Using a hashtable (Dictionary<string, MarketDataExchange>), as suggested by many:
1000000 runs: 88.32 ms
Average: 0.08832 microsecond
Speed increase: 12.36%

使用二进制搜索:结果
百万运行:1031毫秒结果
平均:1.031微秒结果
速度增长:无(性能恶化)

Using a binary search:
1000000 runs: 1031 ms
Average: 1.031 microseconds
Speed increase: none (performance worsened)

让我只想说,它已经真正冷静地看到许多不同的想法的人怎么过这个简单的问题。这对我来说非常有趣,我很感谢大家谁作出了贡献,并提出到目前为止的建议。

Let me just say that it has been really cool to see how many different ideas people had on this simple problem. This was very interesting to me, and I'm quite thankful to everyone who has contributed and made a suggestion so far.

推荐答案

假设每个输入将是一个有效的 ActivCode ,你可以改变枚举值和高度耦合到的GetHashCode 实施:

Assuming every input will be a valid ActivCode, that you can change the enumeration values and highly coupled to the GetHashCode implementation:

enum MarketDataExchange
{
    NONE,
    NBBO = 371857150,
    AMEX = 372029405,
    BSE = 372029408,
    BATS = -1850320644,
    NSE = 372029407,
    CHX = -284236702,
    NYSE = 372029412,
    ARCA = -734575383,
    NASDAQ = 372029421,
    NASDAQ_ADF = -1137859911,
    CBOE = 372029419,
    PHLX = 372029430,
    DIRECTEDGE = 372029429
}

public static MarketDataExchange GetMarketDataExchange(string ActivCode)
{
    if (ActivCode == null) return MarketDataExchange.NONE;

    return (MarketDataExchange)ActivCode.GetHashCode();
}

这篇关于你将如何让这个switch语句尽可能快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆