找回密码
 立即注册

QQ登录

只需一步,快速开始

graper

高级会员

45

主题

63

帖子

1348

积分

高级会员

积分
1348

活字格认证

graper
高级会员   /  发表于:2009-12-11 16:15  /   查看:6128  /  回复:0
Post by "Carl", 02-07-2007, 18:58
-----------------------------------------------------


很多情况下我们用字符串进行 Switch/Case,因为这样有很好的扩展性。
比如:

  1.         private void ProcessCommand(string command, object parameter)
  2.         {
  3.             switch (command)
  4.             {
  5.                 case "New":
  6.                 case "Close":
  7.                 case "Save":
  8.                 case "Load":
  9.                 case "Copy":
  10.                 case "Paste":
  11.                 case "Cut":
  12.                 case "Delete":
  13.                 case "Print":
  14.                 case "PrintPreview":
  15.                 case "Refresh":
  16.                 case "Exit":
  17.                     break;
  18.             }
  19.         }
复制代码
这样如果我们想添加新的Command,只要再写一个case就可以,不用做任何的新的定义。
但是因为字符串的比较性能很差,时间消耗远远大于枚举类型,所以有时候必须对此加以优化。
我曾经在反汇编后的.NET Framework中见过这样的优化方法,很有启发:

  1.       private void ProcessCommand(string command, object parameter)
  2.         {
  3.             switch (command.Length)
  4.             {
  5.                 case 3:
  6.                     switch (command)
  7.                     {
  8.                         case "New":
  9.                         case "Cut":
  10.                             break;
  11.                     }
  12.                     break;
  13.                 case 4:
  14.                     switch (command)
  15.                     {
  16.                         case "Save":
  17.                         case "Load":
  18.                         case "Copy":
  19.                         case "Exit":
  20.                             break;
  21.                     }
  22.                     break;
  23.                 case 5:
  24.                     switch (command)
  25.                     {
  26.                         case "Close":
  27.                         case "Paste":
  28.                         case "Print":
  29.                             break;
  30.                     }
  31.                     break;
  32.                 case 6:
  33.                     switch (command)
  34.                     {
  35.                         case "Delete":
  36.                             break;
  37.                     }
  38.                     break;
  39.                 case 7:
  40.                     switch (command)
  41.                     {
  42.                         case "Refresh":
  43.                             break;
  44.                     }
  45.                     break;
  46.                 case 12:
  47.                     switch (command)
  48.                     {
  49.                         case "PrintPreview":
  50.                             break;
  51.                     }
  52.                     break;
  53.             }
  54.         }
复制代码
用字符串的长度先做判断,这样大大减少了需要比较的次数。
到了.NET 2.0之后,编译器已经可以对这样的Switch/Case自动做优化,其原理是这样的:

  1.       private static Dictionary<string, int> tempTable;
  2.         private static Dictionary<string, int> TempTable
  3.         {
  4.             get
  5.             {
  6.                 if (tempTable == null)
  7.                 {
  8.                     tempTable = new Dictionary<string, int>();
  9.                     tempTable.Add("New", 0);
  10.                     tempTable.Add("Close", 1);
  11.                     tempTable.Add("Save", 2);
  12.                     tempTable.Add("Load", 3);
  13.                     tempTable.Add("Copy", 4);
  14.                     tempTable.Add("Paste", 5);
  15.                     tempTable.Add("Cut", 6);
  16.                     tempTable.Add("Delete", 7);
  17.                     tempTable.Add("Print", 8);
  18.                     tempTable.Add("PrintPreview", 9);
  19.                     tempTable.Add("Refresh", 10);
  20.                     tempTable.Add("Exit", 11);
  21.                 }
  22.                 return tempTable;
  23.             }
  24.         }
  25.         private void ProcessCommand(string command, object parameter)
  26.         {
  27.             switch (TempTable[command])
  28.             {
  29.                 case 0:
  30.                 case 1:
  31.                 case 2:
  32.                 case 3:
  33.                 case 4:
  34.                 case 5:
  35.                 case 6:
  36.                 case 7:
  37.                 case 8:
  38.                 case 9:
  39.                 case 10:
  40.                 case 11:
  41.                     break;
  42.             }
  43.         }
复制代码
首先使用string的hashcode在表中查到一个对应的index,再使用这个index去做switch。有点匪夷所思,但是真的很有效。string的GetHashCode的方法要比Compare快上很多。
看看上面的方法,思路开阔了不少。感觉作一个程序员还是蛮自豪的,因为我们在创造世界。

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部