【问题标题】:Is it possible to optimize large switch on strings?是否可以优化字符串上的大开关?
【发布时间】:2011-08-23 15:01:55
【问题描述】:

我正在浏览我的一个朋友的库,因为他询问了优化,我遇到了这样的一段代码:

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 语句可以以任何方式优化吗?

【问题讨论】:

  • 优化?它是否存在衡量的性能问题?
  • 我愿意赌一美元,在这个程序的某个地方存在一个错误,字符串“twenty-a”被解析为 21。另外,“forty”拼写错误。
  • Mitch Wheat - 不,但在我的书中,你不会将坏代码优化为好代码,而是将好代码优化为更好的代码。
  • @Corey:在我的书中,你不会浪费股东的钱花时间和金钱“优化”(1)已经足够好,(2)可能不是最慢的代码该程序。在花时间快速获取代码之前,先花时间获取代码正确。我只看一眼就发现了两个错误;花时间解决错误。
  • @Corey Ogburn:总会有股东,只是可能不是你传统上认为的股东。也许“利益相关者”是一个更合适的术语,但重点仍然是某个地方的某个人(可能只有你)对这个项目有兴趣或关注。

标签: c# optimization


【解决方案1】:

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

也就是说,我实际上发现在这里使用Dictionary<string, int> switch 更具可读性

【讨论】:

  • 有吗?酷,不知道,你能链接到一个来源吗?
  • 这是一个有趣的知识点。能否提供更多信息的链接?
  • 我也不知道,我很想了解更多。
  • @mafutrct 我手边没有源代码,但您可以使用 Reflector 或反汇编的 .NET 可执行文件自己查看。
  • @James - 为您的“小奇迹”再添一份?
【解决方案2】:

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

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


// elsewhere
return wordsToNumbers[word];

注意:

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

【讨论】:

  • 打败我!只需确保进程以某种方式缓存即可。这样它就不会多次构建字典。
  • 请注意:只有保留字典并在每次调用这个奇怪的月份数字函数时重复使用它才是一个好主意。 每次都构建字典并搜索它是一个好主意。
  • 我似乎记得编译器也会在有利可图的时候使用字典。
  • @Henk - 这也是康拉德所说的。你有相关文档的链接吗?
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    您可以使用字典而不是大开关。就时间而言,开关与字典的时间。我认为字典会更干净,但可能会执行相同的操作。

    【讨论】:

    • 我没有收到加载新答案警告对话框,所以这个答案是多余的。
    【解决方案5】:
    1. 如果需要,请测量。使用分析器。

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

    【讨论】:

      【解决方案6】:

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

      您可以使用 Reflector 进行验证。

      【讨论】:

        猜你喜欢
        • 2018-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-15
        • 2010-09-22
        • 2010-09-22
        • 2011-05-16
        相关资源
        最近更新 更多