近日研读PetShop4 的源代码,发现使用了 IList<> 作为传递一部分数据的载体,比起Grove的用ArrayList作为传递载体少了转型,感觉方便一点,但是用久了,心生疑问,那种性能高一点呢.
今天我就做个简单的性能分析.
首先介绍的数据来源: 一个数据表
数据库是SQLServer 2005 , 该表有1733 条数据
我写了以下代码来测量完成操所用的时间,学过物理的都知道,测量不是一次半次就可以了,需要多次测量来求平均值,才能作为测量值,呵呵
这一段是为了使连接池中有一个连接 , 使得建立连接的时间不会引入到后面的测试当中
其实代码绝大部分是一样的
最后得出的结果如下:
初始化....
开始....
................................................................................
....................
结束
00:00:43.0819488
00:00:07.5007856
00:00:07.5508576
00:00:07.4406992
00:00:12.0873808
大家可以看到,最慢的是 TypedDataTable 他的父类 DataTable 比他快了将近3倍,
IList<> ArrayList 数组是同一个数量级,但是IList 不需要ArrayList那样转型,用起来舒服一点,而且稍稍快一点,(1000 次 Load 进1733条数据,领先0.05秒,少得可怜)而最快的数组,但是数组这里我是知道有多少数据的,所以一开始就设定为 MySysUser[] MyArray = new MySysUser[1800]; 呵呵,至于实际应用中怎么知道改数组多大呢,就看各位牛人了。但是,数组比IList也快不了多少,(1000 次 Load 进1733条数据,领先0.06秒,也是少得可怜),对于长度难以决定的场合IList明显是占有上风的
欢迎大家评论。
今天我就做个简单的性能分析.
首先介绍的数据来源: 一个数据表
CREATE
TABLE
[
dbo
]
.
[
SYS_Users
]
(
[ UserID ] [ int ] IDENTITY ( 1 , 1 ) NOT NULL ,
[ UserName ] [ varchar ] ( 50 ) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[ UserPswd ] [ varchar ] ( 50 ) COLLATE Chinese_PRC_CI_AS NOT NULL ,
CONSTRAINT [ PK_SYS_Users ] PRIMARY KEY CLUSTERED
(
[ UserID ] ASC
) WITH (IGNORE_DUP_KEY = OFF ) ON [ PRIMARY ]
) ON [ PRIMARY ]
[ UserID ] [ int ] IDENTITY ( 1 , 1 ) NOT NULL ,
[ UserName ] [ varchar ] ( 50 ) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[ UserPswd ] [ varchar ] ( 50 ) COLLATE Chinese_PRC_CI_AS NOT NULL ,
CONSTRAINT [ PK_SYS_Users ] PRIMARY KEY CLUSTERED
(
[ UserID ] ASC
) WITH (IGNORE_DUP_KEY = OFF ) ON [ PRIMARY ]
) ON [ PRIMARY ]
数据库是SQLServer 2005 , 该表有1733 条数据
我写了以下代码来测量完成操所用的时间,学过物理的都知道,测量不是一次半次就可以了,需要多次测量来求平均值,才能作为测量值,呵呵
using
System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace MyMain
{
class Program
{
static void Main(string[] args)
{
int i = 0;
Console.WriteLine("初始化....");
string cnString = @"Server=localhost;Database=Education.Database;UID=sa;PassWord=123456;";
SqlConnection cn = new SqlConnection(cnString);
SqlCommand cm = new SqlCommand("select * from SYS_Users", cn);
cn.Open();
SqlDataReader rdr = cm.ExecuteReader();
while (rdr.Read())
{
i++;
}
rdr.Close();
cn.Close();
SqlDataAdapter ada = null;
Console.WriteLine("开始....");
DateTime start;
DateTime end;
TimeSpan[] TS = new TimeSpan[5];
for (int counter = 1; counter <= 100; counter++)
{
start = DateTime.Now;
for (int smallCounter = 1; smallCounter <= 10; smallCounter++)
{
ada = new SqlDataAdapter("select * from SYS_Users", cn);
SYS_UserDS.SYS_UsersDataTable table = new SYS_UserDS.SYS_UsersDataTable();
cn.Open();
ada.Fill(table);
cn.Close();
}
end = DateTime.Now;
TS[0] += end - start;
start = DateTime.Now;
for (int smallCounter = 1; smallCounter <= 10; smallCounter++)
{
cm = new SqlCommand("select * from SYS_Users", cn);
IList<MySysUser> MyList = new List<MySysUser>();
cn.Open();
rdr = cm.ExecuteReader();
while (rdr.Read())
{
MyList.Add(new MySysUser(rdr.GetInt32(0), rdr.GetString(1), rdr.GetString(2)));
}
rdr.Close();
cn.Close();
}
end = DateTime.Now;
TS[1] += end - start;
start = DateTime.Now;
for (int smallCounter = 1; smallCounter <= 10; smallCounter++)
{
cm = new SqlCommand("select * from SYS_Users", cn);
ArrayList MyAl = new ArrayList();
cn.Open();
rdr = cm.ExecuteReader();
while (rdr.Read())
{
MyAl.Add(new MySysUser(rdr.GetInt32(0), rdr.GetString(1), rdr.GetString(2)));
}
rdr.Close();
cn.Close();
}
end = DateTime.Now;
TS[2] += end - start;
start = DateTime.Now;
for (int smallCounter = 1; smallCounter <= 10; smallCounter++)
{
cm = new SqlCommand("select * from SYS_Users", cn);
MySysUser[] MyArray = new MySysUser[1800];
cn.Open();
int flag = 0;
rdr = cm.ExecuteReader();
while (rdr.Read())
{
MyArray[flag] = new MySysUser(rdr.GetInt32(0), rdr.GetString(1), rdr.GetString(2));
flag++;
}
rdr.Close();
cn.Close();
}
end = DateTime.Now;
TS[3] += end - start;
start = DateTime.Now;
for (int smallCounter = 1; smallCounter <= 10; smallCounter++)
{
ada = new SqlDataAdapter("select * from SYS_Users", cn);
DataTable aTable = new DataTable();
cn.Open();
ada.Fill(aTable);
cn.Close();
}
end = DateTime.Now;
TS[4] += end - start;
Console.Write(".");
}
Console.WriteLine();
Console.WriteLine("结束");
foreach (TimeSpan ts in TS)
{
Console.WriteLine(ts);
}
Console.ReadLine();
}
}
}
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace MyMain
{
class Program
{
static void Main(string[] args)
{
int i = 0;
Console.WriteLine("初始化....");
string cnString = @"Server=localhost;Database=Education.Database;UID=sa;PassWord=123456;";
SqlConnection cn = new SqlConnection(cnString);
SqlCommand cm = new SqlCommand("select * from SYS_Users", cn);
cn.Open();
SqlDataReader rdr = cm.ExecuteReader();
while (rdr.Read())
{
i++;
}
rdr.Close();
cn.Close();
SqlDataAdapter ada = null;
Console.WriteLine("开始....");
DateTime start;
DateTime end;
TimeSpan[] TS = new TimeSpan[5];
for (int counter = 1; counter <= 100; counter++)
{
start = DateTime.Now;
for (int smallCounter = 1; smallCounter <= 10; smallCounter++)
{
ada = new SqlDataAdapter("select * from SYS_Users", cn);
SYS_UserDS.SYS_UsersDataTable table = new SYS_UserDS.SYS_UsersDataTable();
cn.Open();
ada.Fill(table);
cn.Close();
}
end = DateTime.Now;
TS[0] += end - start;
start = DateTime.Now;
for (int smallCounter = 1; smallCounter <= 10; smallCounter++)
{
cm = new SqlCommand("select * from SYS_Users", cn);
IList<MySysUser> MyList = new List<MySysUser>();
cn.Open();
rdr = cm.ExecuteReader();
while (rdr.Read())
{
MyList.Add(new MySysUser(rdr.GetInt32(0), rdr.GetString(1), rdr.GetString(2)));
}
rdr.Close();
cn.Close();
}
end = DateTime.Now;
TS[1] += end - start;
start = DateTime.Now;
for (int smallCounter = 1; smallCounter <= 10; smallCounter++)
{
cm = new SqlCommand("select * from SYS_Users", cn);
ArrayList MyAl = new ArrayList();
cn.Open();
rdr = cm.ExecuteReader();
while (rdr.Read())
{
MyAl.Add(new MySysUser(rdr.GetInt32(0), rdr.GetString(1), rdr.GetString(2)));
}
rdr.Close();
cn.Close();
}
end = DateTime.Now;
TS[2] += end - start;
start = DateTime.Now;
for (int smallCounter = 1; smallCounter <= 10; smallCounter++)
{
cm = new SqlCommand("select * from SYS_Users", cn);
MySysUser[] MyArray = new MySysUser[1800];
cn.Open();
int flag = 0;
rdr = cm.ExecuteReader();
while (rdr.Read())
{
MyArray[flag] = new MySysUser(rdr.GetInt32(0), rdr.GetString(1), rdr.GetString(2));
flag++;
}
rdr.Close();
cn.Close();
}
end = DateTime.Now;
TS[3] += end - start;
start = DateTime.Now;
for (int smallCounter = 1; smallCounter <= 10; smallCounter++)
{
ada = new SqlDataAdapter("select * from SYS_Users", cn);
DataTable aTable = new DataTable();
cn.Open();
ada.Fill(aTable);
cn.Close();
}
end = DateTime.Now;
TS[4] += end - start;
Console.Write(".");
}
Console.WriteLine();
Console.WriteLine("结束");
foreach (TimeSpan ts in TS)
{
Console.WriteLine(ts);
}
Console.ReadLine();
}
}
}
SqlConnection cn
=
new
SqlConnection(cnString);
SqlCommand cm = new SqlCommand( " select * from SYS_Users " , cn);
cn.Open();
SqlDataReader rdr = cm.ExecuteReader();
while (rdr.Read())
{
i++;
}
rdr.Close();
cn.Close();
SqlCommand cm = new SqlCommand( " select * from SYS_Users " , cn);
cn.Open();
SqlDataReader rdr = cm.ExecuteReader();
while (rdr.Read())
{
i++;
}
rdr.Close();
cn.Close();
这一段是为了使连接池中有一个连接 , 使得建立连接的时间不会引入到后面的测试当中
其实代码绝大部分是一样的
最后得出的结果如下:
初始化....
开始....
................................................................................
....................
结束
00:00:43.0819488
00:00:07.5007856
00:00:07.5508576
00:00:07.4406992
00:00:12.0873808
大家可以看到,最慢的是 TypedDataTable 他的父类 DataTable 比他快了将近3倍,
IList<> ArrayList 数组是同一个数量级,但是IList 不需要ArrayList那样转型,用起来舒服一点,而且稍稍快一点,(1000 次 Load 进1733条数据,领先0.05秒,少得可怜)而最快的数组,但是数组这里我是知道有多少数据的,所以一开始就设定为 MySysUser[] MyArray = new MySysUser[1800]; 呵呵,至于实际应用中怎么知道改数组多大呢,就看各位牛人了。但是,数组比IList也快不了多少,(1000 次 Load 进1733条数据,领先0.06秒,也是少得可怜),对于长度难以决定的场合IList明显是占有上风的
欢迎大家评论。