在性能方面使用枚举而不是字符串数组是否更有效?
我决定测试一个特定的方法IsDefined,而不是检查字符串数组中的匹配。我创建了一个秒表对象来测试每个人的运行时间 代码如下:
在Main类之外定义一个枚举:
enum Color : byte { red, blue, green }
Inside Main:
string[] colArr = new string[] { "red", "blue", "green" };
string input = "green";
Stopwatch s1 = new Stopwatch();
int loopIterations = 0;
s1.Restart();
while (loopIterations++ < 100000000)
foreach (var blah in colArr)
if (blah == input)
break;
s1.Stop();
Console.WriteLine("Runtime for foreach loop: {0}", s1.Elapsed);
loopIterations = 0;
s1.Restart();
while (loopIterations++ < 100000000)
if (Enum.IsDefined(typeof(Color), input))
continue;
s1.Stop();
Console.WriteLine("Runtime for IsDefined method returned value: {0}", s1.Elapsed);
我的输出如下:
Runtime for foreach loop: 00:00:01.4862817
Runtime for IsDefined method returned value: 00:00:09.3421654
Press any key to continue . . .
所以我想问一下 - 假设我写的代码不是,比如,愚蠢或者什么 - 这些数字是正常的,如果它们是,那么使用枚举比使用字符串数组更好,特别是那种工作都会吗?
答案 0 :(得分:2)
对于初学者而言,使用枚举而非性能的一个重要原因是代码的可维护性。例如,试图找到所有参考文献&#39;在Visual Studio中只需点击几下即可完成Color.red。试图找到字符串并不容易。总是键入字符串也容易出错。虽然使用常量可以稍微缓解这两个问题,但使用枚举更容易。
枚举可以看作是一个常量整数值,它具有良好的性能并且具有诸如使用标志(掩码)之类的好处。比较int会比比较一个字符串更快,但这不是这里发生的事情。大多数情况下,您希望针对特定值执行某些操作,并且可以测试if(someString == "red")
与if(someColVal == Color.red)
,在这种情况下,后者应该更快。
使用Enum.IsDefined
检查枚举中是否存在值可能会更慢,但该函数必须每次在此循环中查找枚举值。
同时第一个测试有一个预定义的数组。对于性能与第一次测试的严格比较,您可以执行以下操作:
var colvalues = Enum.GetValues(typeof(Color)).Cast<Color>().ToArray(); // or hardcode: var colvalues = new[]{Color.red, Color.blue, Color.green};
var colinput = Color.red;
while (loopIterations++ < 100000000)
foreach (var blah in colvalues)
if (blah == colinput)
break;
尽管如上所述,查找enum
中是否存在值通常不是其主要功能(通常用于检查特定值)。但是,它的整数基数允许其他方法检查值是否在预期范围内,例如掩码检查或>
,>=
,<
或{{1 }}
编辑查看有关用户输入的评论:主要是控制输入,例如:用户显示菜单。在控制台环境中,可以使用枚举的编号构建菜单。
例如,枚举<=
,菜单
红色的
蓝色
3.绿色
用户输入是整数。另一方面,如果需要输入,enum Color : byte { red = 1, blue, green }
将阻止必须重新键入值,并且易于使用。为了提高性能,可以使用IsDefined
答案 1 :(得分:1)
枚举的正常用法是表示逻辑状态或有限范围的选项:在您的示例中,例如,一种产品只有三种颜色。在这种情况下使用字符串来表示颜色有两个缺点:您可能会错误地在代码中的某处拼错颜色名称,并且难以跟踪错误;和字符串比较本质上比比较枚举(基本上比较整数)慢。
IsDefined()
使用类型反射,因此应该比直接字符串比较慢。在某些情况下,您希望将枚举转换为字符串或从字符串转换枚举:通常在执行输入/输出(如保存或恢复配置)时。这种情况比较慢,但输入/输出通常由存储介质和网络的缓慢所主导,所以它很少有什么大不了的。
答案 2 :(得分:0)
我知道这是一篇很老的文章,但是注意到比较的代码片段循环并没有以类似的方式进行循环。 与第一个循环一样,一旦在字符串数组中找到字符串,就让循环中断,但在第二种情况下,不要让循环停止,而是在Enum.IsDefined找到该值时继续循环。
当您发现枚举值实际中断循环时,枚举场景运行得更快...