是否可以优化字符串上的大型开关?

时间:2011-08-23 15:01:55

标签: c# optimization

我正在浏览我的图书馆的一位朋友,因为他询问了优化,我遇到了一段代码:

long digit = 0;

switch (word) {
    case "zero":
        digit = 0;
        break;
    case "a":
    case "one":
        digit = 1;
        break;
    case "two":
        digit = 2;
        break;
    case "three":
        digit = 3;
        break;
    case "four":
        digit = 4;
        break;
    case "five":
        digit = 5;
        break;
    case "six":
        digit = 6;
        break;
    case "seven":
        digit = 7;
        break;
    case "eight":
        digit = 8;
        break;
    case "nine":
        digit = 9;
        break;
    case "ten":
        digit = 10;
        break;
    case "eleven":
        digit = 11;
        break;
    case "twelve":
        digit = 12;
        break;
    case "thirteen":
        digit = 13;
        break;
    case "fourteen":
        digit = 14;
        break;
    case "fifteen":
        digit = 15;
        break;
    case "sixteen":
        digit = 16;
        break;
    case "seventeen":
        digit = 17;
        break;
    case "eighteen":
        digit = 18;
        break;
    case "nineteen":
        digit = 19;
        break;
    case "twenty":
        digit = 20;
        break;
    case "thirty":
        digit = 30;
        break;
    case "fourty":
        digit = 40;
        break;
    case "fifty":
        digit = 50;
        break;
    case "sixty":
        digit = 60;
        break;
    case "seventy":
        digit = 70;
        break;
    case "eighty":
        digit = 80;
        break;
    case "ninety":
        digit = 90;
        break;
}

return digit;

我在这里看到了一些关于exactly how a switch might work的问题,但他们很方便地没有提到带字符串的情况。像上面那样的switch语句能否以任何方式进行优化?

6 个答案:

答案 0 :(得分:11)

正如奥德德所说,你可以将它们放在Dictionary中。但事实上,.NET编译器已经为您完成了这项工作:它构建了一个跳转表(通过Dictionary<string, SomeDelegate>),允许在O(1)中打开值。

那说,我实际上发现Dictionary<string, int> switch更具可读性

答案 1 :(得分:9)

您可以将这些内容放入Dictionary<string,int>并返回int作为字符串键。

var wordsToNumbers = new Dictionary<string,int>();
wordsToNumbers.Add("one", 1);
...
wordsToNumbers.Add("ninety", 90);


// elsewhere
return wordsToNumbers[word];

注意:

正如其他人在评论中指出的那样 - 我们的想法是构建字典一次并重复使用它。一种方法是使用一个字段并在构造函数中填充它,然后在其他方法中使用它。

答案 2 :(得分:2)

在这种情况下,更好的优化可能是拥有静态字典:

private static readonly Dictionary<string, long> _lookup = new Dictionary<string, long>
   {
       { "one", 1 },
       { "two", 2 },
       { "three", 3 },
       // etc...
   }

然后只需访问使用:

var number = "one";
var result = _lookup[number];

答案 3 :(得分:1)

您可以使用字典而不是大量的开关。至于时间,交换时间与字典的时间。我认为字典会更干净,但可能会表现相同。

答案 4 :(得分:0)

  1. 测量是否需要。使用分析器。

  2. 最简单的方法是字典。它也非常适合您的用例。

答案 5 :(得分:0)

当字符串数量变得足够大以至于散列表比一系列比较更快时,开启字符串将切换到使用散列表。

您可以使用Reflector验证这一点。