性能相差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而不同,但是经过我自己的测试,的确发现其中的差异是非常巨大的。所以无论是有兴趣或者是没兴趣的朋友,都注意一下。或者是自己做一下测试。