| xin3721网络学院重要提示:其实我自己对执行速度这个问题本来并没有什么兴趣,因为以前的经验告诉我:除非是运算密集型的程序,否则脚本语言和编译型语言使用起来速度没有多大差别。但是我们公司有个人知道我的想法以后,天天在我耳边嚷嚷脚本运行速度太慢,那好吧,让我用实验来说服你。 |
其实我自己对执行速度这个问题本来并没有什么兴趣,因为以前的经验告诉我:除非是运算密集型的程序,否则脚本语言和编译型语言使用起来速度没有多大差别。但是我们公司有个人知道我的想法以后,天天在我耳边嚷嚷脚本运行速度太慢,那好吧,让我用实验来说服你。不过这一试,还真的出现了吓人一跳的结果。
我构思的实验覆盖到下面几个我认为是实际项目中比较有代表性的场景:
1. 访问一个稍大的数据表,遍历所有记录;
2. 生成并操作一个列表;
3. 生成并操作一个字典;
4. 通过反射动态加载并调用一个方法。
C#部分的代码,编译时使用了/debug-和/optimize+:
|
以下为引用的内容:
using System; using System.Data.SqlClient; using System.Diagnostics; using System.Collections.Generic; using System.Reflection;
namespace Test { class Test { public static void Main(string[] args) { Console.WriteLine("C#:"); Measure(TestDb, "TestDb"); Measure(TestList, "TestList"); Measure(TestDict, "TestDict"); Measure(TestReflection, "TestReflection"); } delegate void FuncDelegate(); static void Measure(FuncDelegate func, string funcName) { Stopwatch sw = new Stopwatch(); sw.Start(); func(); sw.Stop(); Console.WriteLine(" {0} used {1} ms", funcName, sw.ElapsedMilliseconds); } static void TestDb() { using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); SqlCommand cmd = new SqlCommand(sql, conn); SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { var id = reader["Id"]; var code = reader["Code"]; var cargoCode = reader["CargoCode"]; var length = reader["Length"]; var width = reader["Width"]; var height = reader["Height"]; var vol = reader["Vol"]; var pallet = reader["Pallet"]; } reader.Close(); cmd.Dispose(); conn.Close(); } } static void TestList() { var list = new List(); const int count = 100000; for (int i=0; i list.Add(string.Format("item{0}", i)); for (int i=count-1; i>=0; i--) list.RemoveAt(i); } static void TestDict() { var dict = new Dictionary(); const int count = 100000; for (int i=0; i dict[string.Format("key{0}", i)] = string.Format("&#118alue{0}", i); for (int i=0; i dict.Remove(string.Format("key{0}", i)); } static void TestReflection() { Assembly assem = Assembly.LoadFrom("Lib.dll"); Type type = assem.GetType("Lib.TestLib"); const int count = 100000; ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes); MethodInfo mi = type.GetMethod("GetMessage"); for (int i=0; i { object obj = ci.Invoke(null); // Activator.CreateInstance(type); mi.Invoke(obj, new object[] { "name" } ); } } const string connStr = "Integrated Security=SSPI; Initial Catalog=test; Data Source=."; const string sql = "select * from CargoPackageTypes"; } } |