想比较 as , is , typeof , GetType , 强制类型转换 这几个哪个性能更好。
以下是测试代码:
object a = "hello"; Stopwatch sw = Stopwatch.StartNew(); sw.Restart(); for (int i = 0; i < 10000; i++) { var d = a as string; } Console.WriteLine("As:" + sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < 10000; i++) { var d = (string)a; } Console.WriteLine("(string):" + sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < 10000; i++) { var d = a.GetType(); } Console.WriteLine("GetType:" + sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < 10000; i++) { var d = typeof(string); } Console.WriteLine("typeof:" + sw.ElapsedTicks); for (int i = 0; i < 10000; i++) { var d = a is int; } Console.WriteLine("Is:" + sw.ElapsedTicks);
单元测试下Debug | ||||||
第一次 | 第二次 | 第三次 | 平均 | |||
As:142 | As:147 | As:160 | As:150 | |||
Is:157 | Is:152 | Is:177 | Is:162 | |||
(string):146 | (string):147 | (string):165 | (string):153 | |||
typeof:611 | typeof:616 | typeof:687 | typeof:637 | |||
GetType:314 | GetType:313 | GetType:353 | GetType:327 | |||
单元测试下Release | ||||||
第一次 | 第二次 | 第三次 | 平均 | |||
As:21 | As:20 | As:20 | As:20 | |||
Is:20 | Is:20 | Is:20 | Is:20 | |||
(string):98 | (string):98 | (string):98 | (string):98 | |||
typeof:20 | typeof:20 | typeof:20 | typeof:20 | |||
GetType:333 | GetType:333 | GetType:348 | GetType:339 | |||
Console程序Debug | ||||||
第一次 | 第二次 | 第三次 | 平均 | |||
As:183 | As:184 | As:184 | As:184 | |||
Is:295 | Is:295 | Is:411 | Is:334 | |||
(string):231 | (string):177 | (string):241 | (string):216 | |||
typeof:278 | typeof:216 | typeof:213 | typeof:236 | |||
GetType:477 | GetType:430 | GetType:424 | GetType:443 | |||
Console程序Release | ||||||
第一次 | 第二次 | 第三次 | 平均 | |||
As:11 | As:11 | As:11 | As:11 | |||
Is:6 | Is:6 | Is:6 | Is:6 | |||
(string):45 | (string):45 | (string):45 | (string):45 | |||
typeof:7 | typeof:6 | typeof:6 | typeof:6 | |||
GetType:6 | GetType:7 | GetType:7 | GetType:7 |
单元测试下,性能是不准的。
Release 下性能 比较: is = typeof 高于 GetType 高于 As 高于 强制类型转换。
----------------------------------------------------------
持续对以上结果表示怀疑,增加循环次数。
using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using MyCmn; using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; using System.Diagnostics; using System.Threading; using System.Linq; namespace Test { public class Main_Cls { const int TIMES = 100000; public static void Main() { object a = "hello world"; var str = "hello world!"; Stopwatch sw = Stopwatch.StartNew(); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = typeof(string); } MyConsole.WriteLine("typeof:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = a.GetType(); } MyConsole.WriteLine("GetType:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = object.Equals(a, null); } MyConsole.WriteLine("object.Equals:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = default(string); } MyConsole.WriteLine("default:", sw.ElapsedTicks); MyConsole.WriteLine("String______________"); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = "hello"; } MyConsole.WriteLine("new string:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = str.Length; } MyConsole.WriteLine("String.Length:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = string.IsNullOrEmpty(str); } MyConsole.WriteLine("string.IsNullOrEmpty:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = a as string; } MyConsole.WriteLine("As:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = a is int; } MyConsole.WriteLine("Is:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = (string)a; } MyConsole.WriteLine("(string):", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = i.ToString(); } MyConsole.WriteLine("ToString:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = i.AsString(); } MyConsole.WriteLine("AsString:", sw.ElapsedTicks); MyConsole.WriteLine(" ______________String"); MyConsole.WriteLine("类型转换______________"); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = DateTime.Now; } MyConsole.WriteLine("DateTime:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = Guid.NewGuid(); } MyConsole.WriteLine("Guid:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = i.AsDecimal(); } MyConsole.WriteLine("AsDecimal:", sw.ElapsedTicks); sw.Restart(); for (int i = 0; i < TIMES; i++) { var d = i.AsFloat(); } MyConsole.WriteLine("AsFloat:", sw.ElapsedTicks); MyConsole.WriteLine(" ______________类型转换"); sw.Restart(); for (int i = 0; i < TIMES; i++) { var t = typeof(string).GetProperties(); } MyConsole.WriteLine("Reflect:", sw.ElapsedTicks); } } public static class MyConsole { public static void WriteLine(string title, long msg = 0) { if (msg > 0) { Console.WriteLine(string.Format("{0,27} {1,-8}", title, msg)); } else { Console.WriteLine(title); } } } }
结果:
typeof: 45
GetType: 44
object.Equals: 1620
default: 44
String______________
new string: 45
String.Length: 45
string.IsNullOrEmpty: 900
As: 44
Is: 46
(string): 391
ToString: 53567
AsString: 146645
______________String
类型转换______________
DateTime: 35750
Guid: 69539
AsDecimal: 72932
AsFloat: 289442
______________类型转换
Reflect: 71428
As 的性能略高于 Is , 但 判等的性能却是出忽意料的差。
再加入 == 判定测试 和 a.Equals 的判定测试:
typeof: 58
GetType: 50
object.Equals: 1736
==: 49
a.Equals: 2420
default: 50
String______________
new string: 50
String.Length: 50
string.IsNullOrEmpty: 969
As: 50
Is: 50
(string): 441
ToString: 52179
AsString: 139356
______________String
类型转换______________
DateTime: 35400
Guid: 69725
AsDecimal: 82086
AsFloat: 321944
______________类型转换
Reflect: 63618
查看源码:
public static bool IsNullOrEmpty(string value) { if (value != null) { return (value.Length == 0); } return true; } |