性能相差7千倍的ToString()方法
ToString()方法大概是.Net时被用得最多的方法了,所有类型都,引用的,值的,都传承了这个从祖先Object开始的光荣传统。调用一次ToString,相当于惊堂木“啪”一下,大喝“堂下案犯报上名来”,这家伙就全招了。 可是写程序如查案,形形色色的人都有,对于些记性差,反应迟钝的家伙,就没那么顺利了。梅(枚)举人就是其中之一,来审问下看看:
程序代码:static void testEnumToString()
{
var day = DayOfWeek.Wednesday;
string value = null;
for (int i = 0; i < 1000000; i++)
{
value = day.ToString();
}
Console.WriteLine(value);
}整理下结果:次数 1 2 3 4
时间(ms) 7135 7009 7174 7010
看上去没什么,不过根据以往的断案经验,其中似有猫腻。本所以继续下面的代码:
程序代码:static void testEnumToString2()
{
var day = DayOfWeek.Wednesday;
string value = null;
for (int i = 0; i < 1000000; i++)
{
switch (day)
{
case DayOfWeek.Friday:
value = "Friday";
break;
case DayOfWeek.Monday:
value = "Monday";
break;
case DayOfWeek.Saturday:
value = "Saturday";
break;
case DayOfWeek.Sunday:
value = "Sunday";
break;
case DayOfWeek.Thursday:
value = "Thursday";
break;
case DayOfWeek.Tuesday:
value = "Tuesday";
break;
case DayOfWeek.Wednesday:
value = "Wednesday";
break;
default:
break;
}
}
Console.WriteLine(value);
}结果:
次数 1 2 3 4
时间(ms) 2 1 1 1
再使用Reflector查看了一下。
程序代码:public override string ToString()
{
return InternalFormat((RuntimeType) base.GetType(), this.GetValue());
}
private static string InternalFormat(RuntimeType eT, object value)
{
if (eT.IsDefined(typeof(FlagsAttribute), false))
{
return InternalFlagsFormat(eT, value);
}
string name = GetName(eT, value);
if (name == null)
{
return value.ToString();
}
return name;
}在tostring()中用到了反射,所以是以时间换空间的做法,虽然基本不用写代码,而且占用的空间也少,但是却大大地浪费了时间。
相对于switch方法而言,没有将结果字符串硬编码在处理函数中,以后枚举中增加或删除某一项,也不影响调用代码,可维护性相对更好一些。但是也应该看到,这是一种空间换时间的做法,避开了反射,但是系统需要额外存储一个字典对象,占用的内存要比原来多一些。
不过在实际的项目中应该如何运用,这就得看具体情况了,呵呵。
其中的数据虽然会因为不同的PC而不同,但是经过我自己的测试,的确发现其中的差异是非常巨大的。所以无论是有兴趣或者是没兴趣的朋友,都注意一下。或者是自己做一下测试。




