可能是由于小弟半路出家的原因,对Asp.Net没有很系统的学习过,也谈不上精通。对于页面输出数据有些自己的看法,还请各位一起来讨论下。 对于在页面中实现循环输出数据库的一些数据,一般使用的方法有DataGrid、DataList和Repeater。但是本人今天做的实验是使用以速度和性能具称的Repeater与Literal输出。 Repeater输出应该不用解释了吧,而Literal的输出其实也就是利用SqlDataReader循环给Literal赋值来实现。然后利用在服务器代码不同位置放置一个计算时间的参数。通过分析在执行的不同时间所花费的时间来对比二种方法所使用的时间。使用的数据库是有10000条纪录的笑话MSSQL数据库。Repeater页面代码:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div>
<li>
<%# DataBinder.Eval(Container.DataItem, "ID")%>
</li>
<li>
<%# DataBinder.Eval(Container.DataItem, "Name")%>
</li>
<li>
<%# DataBinder.Eval(Container.DataItem, "Source")%>
</li>
<li>
<%# DataBinder.Eval(Container.DataItem, "Ins_Time")%>
</li>
</div>
</ItemTemplate>
</asp:Repeater>
Repeater服务器代码:
protected void Page_Load(object sender, EventArgs e)
{
DateTime t1, t2, t3, t4;
t1 = DateTime.Now;//开始的时间
SqlConnection myConnection = SQLConSql.createCon();//建立连接
SqlCommand myCommand = new SqlCommand("SELECT top 10000 * FROM [HS_Y_J_2_Joke]", myConnection);
myConnection.Open();
Repeater1.DataSource = myCommand.ExecuteReader();
t2 = DateTime.Now;//读取数据后的时间
Repeater1.DataBind();
myConnection.Close();
t3 = DateTime.Now;//绑定到Repeater1后的时间
TimeSpan ts1 = t2.Subtract(t1);//数据库上耗费的时间
TimeSpan ts2 = t3.Subtract(t2);//绑定耗费的时间
Response.Write("myCommand.ExecuteReader完成使用" + ts1 + "<br>Repeater1.DataBind()使用" + ts2 + "<br>");
}
####################################################################
Literal 页面代码:
<body>
<asp:Literal ID="Literal1" runat="server"/>
</body>
Literal 服务器代码:
public static string n = ((char)13).ToString();
protected void Page_Load(object sender, EventArgs e)
{
DateTime t1, t2, t3, t4;
t1 = DateTime.Now;//开始的时间
SqlConnection myConnection = SQLConSql.createCon();//这里被封装起来了的
SqlCommand myCommand = new SqlCommand("SELECT top 10000 * FROM [HS_Y_J_2_Joke]", myConnection);//查询语句一样
myConnection.Open();
SqlDataReader drNewUser = myCommand.ExecuteReader();
t2 = DateTime.Now;//数据库方面的时间
StringBuilder strHtml = new StringBuilder();
while (drNewUser.Read())
{
strHtml.Append(n + "<div>");
strHtml.Append(n + "<li>");
strHtml.Append(n + drNewUser.GetInt32(0));
strHtml.Append(n + "</li>");
strHtml.Append(n + "<li>");
strHtml.Append(n + drNewUser.GetString(1));
strHtml.Append(n + "</li>");
strHtml.Append(n + "<li>");
strHtml.Append(n + drNewUser.GetString(2));
strHtml.Append(n + "</li>");
strHtml.Append(n + "<li>");
strHtml.Append(n + drNewUser.GetDateTime(5));
strHtml.Append(n + "</li>");
strHtml.Append(n + "</div>");
}
drNewUser.Close();
drNewUser.Dispose();
myConnection.Close();
this.Literal1.Text=strHtml.ToString();
t3 = DateTime.Now;//把代码填充到Literal1后的时间
TimeSpan ts1 = t2.Subtract(t1);//数据库耗费的时间
TimeSpan ts2 = t3.Subtract(t2);//把代码填充到Literal1耗费的时间
Response.Write("drNewUser.Read完成使用" + ts1 + "<br>显示到Literal1使用" + ts2 + "<br>");
}
###################################################################
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div>
<li>
<%# DataBinder.Eval(Container.DataItem, "ID")%>
</li>
<li>
<%# DataBinder.Eval(Container.DataItem, "Name")%>
</li>
<li>
<%# DataBinder.Eval(Container.DataItem, "Source")%>
</li>
<li>
<%# DataBinder.Eval(Container.DataItem, "Ins_Time")%>
</li>
</div>
</ItemTemplate>
</asp:Repeater>
Repeater服务器代码:
protected void Page_Load(object sender, EventArgs e)
{
DateTime t1, t2, t3, t4;
t1 = DateTime.Now;//开始的时间
SqlConnection myConnection = SQLConSql.createCon();//建立连接
SqlCommand myCommand = new SqlCommand("SELECT top 10000 * FROM [HS_Y_J_2_Joke]", myConnection);
myConnection.Open();
Repeater1.DataSource = myCommand.ExecuteReader();
t2 = DateTime.Now;//读取数据后的时间
Repeater1.DataBind();
myConnection.Close();
t3 = DateTime.Now;//绑定到Repeater1后的时间
TimeSpan ts1 = t2.Subtract(t1);//数据库上耗费的时间
TimeSpan ts2 = t3.Subtract(t2);//绑定耗费的时间
Response.Write("myCommand.ExecuteReader完成使用" + ts1 + "<br>Repeater1.DataBind()使用" + ts2 + "<br>");
}
####################################################################
Literal 页面代码:
<body>
<asp:Literal ID="Literal1" runat="server"/>
</body>
Literal 服务器代码:
public static string n = ((char)13).ToString();
protected void Page_Load(object sender, EventArgs e)
{
DateTime t1, t2, t3, t4;
t1 = DateTime.Now;//开始的时间
SqlConnection myConnection = SQLConSql.createCon();//这里被封装起来了的
SqlCommand myCommand = new SqlCommand("SELECT top 10000 * FROM [HS_Y_J_2_Joke]", myConnection);//查询语句一样
myConnection.Open();
SqlDataReader drNewUser = myCommand.ExecuteReader();
t2 = DateTime.Now;//数据库方面的时间
StringBuilder strHtml = new StringBuilder();
while (drNewUser.Read())
{
strHtml.Append(n + "<div>");
strHtml.Append(n + "<li>");
strHtml.Append(n + drNewUser.GetInt32(0));
strHtml.Append(n + "</li>");
strHtml.Append(n + "<li>");
strHtml.Append(n + drNewUser.GetString(1));
strHtml.Append(n + "</li>");
strHtml.Append(n + "<li>");
strHtml.Append(n + drNewUser.GetString(2));
strHtml.Append(n + "</li>");
strHtml.Append(n + "<li>");
strHtml.Append(n + drNewUser.GetDateTime(5));
strHtml.Append(n + "</li>");
strHtml.Append(n + "</div>");
}
drNewUser.Close();
drNewUser.Dispose();
myConnection.Close();
this.Literal1.Text=strHtml.ToString();
t3 = DateTime.Now;//把代码填充到Literal1后的时间
TimeSpan ts1 = t2.Subtract(t1);//数据库耗费的时间
TimeSpan ts2 = t3.Subtract(t2);//把代码填充到Literal1耗费的时间
Response.Write("drNewUser.Read完成使用" + ts1 + "<br>显示到Literal1使用" + ts2 + "<br>");
}
###################################################################
解决方案 »
- 从服务端获得时间,然后在客户端保持时间更新 .net 如何写
- isapi伪静态化时 url中有汉字 如何写正则表达式 --在线等
- 了解泛型的高手请进,急,急,急!!!
- 问个问题,Tree.TreeNodeSrc的属性会导致一个文件被锁定,怎么办
- 机器装了oracle之后就不能使用asp.net,恭候解决方法。
- 只要我一加aspnetpager控件,就有下面的问题!!????
- 怎么在后台验证邮件格式?
- 为什么修改程序之后,将bin目录下的dll和pdb文件上传到服务器之后,网站所有用户的Session都被清空
- 填充数据到数据集时,系统提示的出错的信息:
- 关于DataDrid控件的问题,在线等待!
- 你一定也会遇到的问题,进来拿分吧.
- 能否快速的将对象保存为一个DataSet?
上面就是使用Repeater和Literal1的二种方法,连接数据库方法一样,所输出的代码也是一样的,只是方法不一样而已。然后在二个页面里面均放置了一个获取页面执行时间的控件,ascx代码如下:
DateTime startTime;
void Page_Init(Object sender, EventArgs e)
{
startTime = DateTime.Now;
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
DateTime endTime = DateTime.Now;
TimeSpan aaa = endTime.Subtract(startTime);
try
{
Response.Write("整个页面执行时间"+Convert.ToString(aaa.TotalSeconds).Substring(0, 5) + " S");
}
catch
{
Response.Write("整个页面执行时间"+aaa.TotalSeconds.ToString()+" S");
}
}
上面的代码是为了计算整个页面全部执行时间的。
好了 ,接下来我们来看结果吧!.之前是秒
##################################################
Repeater结果:
myCommand.ExecuteReader完成使用00:00:00(几乎是瞬间)
Repeater1.DataBind()使用00:00:00.8906250
整个页面执行时间1.875 S
.........(内容)
跟踪信息 (部分)
类别 消息 From First(s) From Last(s)
aspx.page Begin PreInit
aspx.page End PreInit 3.71555602737219E-05 0.000037
aspx.page Begin Init 6.78857229061235E-05 0.000031
aspx.page End Init 0.000110069855246966 0.000042
aspx.page Begin InitComplete 0.000134374620238047 0.000024
aspx.page End InitComplete 0.000156165099195568 0.000022
aspx.page Begin PreLoad 0.000174603196775009 0.000018
aspx.page End PreLoad 0.000203657168718371 0.000029
aspx.page Begin Load 0.000223492091872012 0.000020
aspx.page End Load 0.8810139277478 0.880790
aspx.page Begin LoadComplete 0.881087959503233 0.000074
aspx.page End LoadComplete 0.881110029347305 0.000022
aspx.page Begin PreRender 0.881130143635574 0.000020
aspx.page End PreRender 0.887943300056292 0.006813
aspx.page Begin PreRenderComplete 0.888015096890806 0.000072
aspx.page End PreRenderComplete 0.888037725465108 0.000023
aspx.page Begin SaveState 1.97402742527332 1.085990
aspx.page End SaveState 1.97406541892894 0.000038
aspx.page Begin SaveStateComplete 1.9740872094079 0.000022
aspx.page End SaveStateComplete 1.97410899988686 0.000022
aspx.page Begin Render 1.97412771734955 0.000019
aspx.page End Render 3.37334046645593 1.399213
控件树
控件 UniqueID 类型 呈现大小字节数(包括子级) ViewState 大小字节数(不包括子级) ControlState 大小字节(不包括子级)
__Page ASP.default3_aspx 4118864 0 0
ctl02 System.Web.UI.LiteralControl 171 0 0
ctl00 System.Web.UI.HtmlControls.HtmlHead 41 0 0
ctl01 System.Web.UI.HtmlControls.HtmlTitle 28 0 0
ctl03 System.Web.UI.LiteralControl 10 0 0
DoneInTime1 ASP.webusercontrol_doneintime_ascx 7 0 0
ctl04 System.Web.UI.LiteralControl 10 0 0
Repeater1 System.Web.UI.WebControls.Repeater 4118605 0 0
###################################################################
Literal1结果:
.........(内容)
drNewUser.Read完成使用00:00:00
显示到Literal1使用00:00:00.3437500
整个页面执行时间0.359 S
跟踪信息
类别 消息 From First(s) From Last(s)
aspx.page Begin PreInit
aspx.page End PreInit 3.57587346995219E-05 0.000036
aspx.page Begin Init 6.20190554944832E-05 0.000026
aspx.page End Init 9.80571553088451E-05 0.000036
aspx.page Begin InitComplete 0.000126831762137367 0.000029
aspx.page End InitComplete 0.000148342875980048 0.000022
aspx.page Begin PreLoad 0.000167060338674329 0.000019
aspx.page End PreLoad 0.00018549843625377 0.000018
aspx.page Begin Load 0.000203657168718371 0.000018
aspx.page End Load 0.344751916793894 0.344548
aspx.page Begin LoadComplete 0.344812539023814 0.000061
aspx.page End LoadComplete 0.34483712315392 0.000025
aspx.page Begin PreRender 0.345157554940642 0.000320
aspx.page End PreRender 0.345196945421834 0.000039
aspx.page Begin PreRenderComplete 0.345217339075218 0.000020
aspx.page End PreRenderComplete 0.345242481935553 0.000025
aspx.page Begin SaveState 0.346042024894225 0.000800
aspx.page End SaveState 0.34607806299404 0.000036
aspx.page Begin SaveStateComplete 0.346098736012538 0.000021
aspx.page End SaveStateComplete 0.346119409031036 0.000021
aspx.page Begin Render 0.346137567763501 0.000018
aspx.page End Render 0.357179753292667 0.011042
控件树
控件 UniqueID 类型 呈现大小字节数(包括子级) ViewState 大小字节数(不包括子级) ControlState 大小字节(不包括子级)
__Page ASP.default4_aspx 958874 0 0
ctl02 System.Web.UI.LiteralControl 171 0 0
ctl00 System.Web.UI.HtmlControls.HtmlHead 41 0 0
ctl01 System.Web.UI.HtmlControls.HtmlTitle 28 0 0
ctl03 System.Web.UI.LiteralControl 22 0 0
DoneInTime1 ASP.webusercontrol_doneintime_ascx 7 0 0
ctl04 System.Web.UI.LiteralControl 10 0 0
Literal1 System.Web.UI.WebControls.Literal 958605 0 0
ctl05 System.Web.UI.LiteralControl 18 0 0
##################################################### 好了,下面就上面的数据做分析吧,
对于第一个输出的时间是 实现数据库互交的时间,第一次刷新时候还是很短时间的,刷新几次后就边0了...
关键是第二个时间,也就是把查询的结果通过Repeater和Literal输出到页面,
Repeater的绑定共花费了---------------------------------0.8906250秒
Literal利用StringBuilder 以SqlDataReader 来循环输出用了0.3437500秒
结论是Repeater把结果输出要比Literal多至少一倍以上的时间。
通过页面里面设置了 Trace="true" 我们还可以看到更多的东西。
相对而言Repeater耗费了更多的服务器资源与大小。而且实际在输出时候也没有Literal快。 那是否可以推论下,使用Literal来实现数据的输出是否能够代替Repeater,当然 这里先不讨论分页方面的因数。而且在页面里面很多地方都没用到分页,那在实际应用中是否能够用Literal来代替Repeater呢?!!就比如一个网站的首业,肯定有很多新闻列表,都只局限于显示前10条新闻,或者是带图片。是否在首业要从数据库读取数据显示出来都可以用Literal来实现了呢? 性能是不是就比Repeater、datalilst、DataGrid、高呢? 但是看了一些站点的源码,却很少用Literal来实现数据输出。所以才会有以上的疑问,其实使用Laber和Literal是一样效果的,只不过Laber在代码里面会多个span出来。不知道我上面使用的方法和我自己的一些分析是否正确,还请大家指出。同时希望大家能够就我的Literal来代替Repeater观点一起来探讨。
整个页面执行时间
Repeater 1.875 S
Literal 0.359 S
数据库查询时间基本上都是0秒
Repeater的绑定 0.8906250秒
Literal 输出用了0.3437500秒
那Literal 的页面 基本上输出完了整个页面的时间也差不多就这么多
而Repeater却有1秒时间在其他地方,或者是绑定前 ,也或者是绑定后。具体情况也不清楚...
Repeater内部要执行循环,解析子控件等等等等 更何况LZ的代码使用反射绑定数据,绑定过程也要耗时...
记得坛子里有篇RPT 和 DG对比的帖子来着
DataBinder.Eval(Container.DataItem, "ID")除掉这个性能损耗,其实双方差不多。Repeater虽然需要多执行一些代码,但与数据库操作比起来毕竟是小头。Repeater能让程序结构看起来更清晰,如前台写的数据绑定。
倒也不能这样说,因为实际上性能损耗在DataBinder.Eval上,微软也建议你不要这样写。
为了开发效率性能损耗是必然的,关键是损耗的程度,另外自己要清楚哪些地方存在性能损耗,不能把微软的东西拿来就用。
那请问下如何写才不损耗呢