可能是由于小弟半路出家的原因,对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>");
    }
###################################################################

解决方案 »

  1.   


    上面就是使用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观点一起来探讨。
      

  2.   

    还有一个就是
    整个页面执行时间
    Repeater  1.875 S 
    Literal   0.359 S 
    数据库查询时间基本上都是0秒
    Repeater的绑定  0.8906250秒
    Literal 输出用了0.3437500秒
    那Literal 的页面 基本上输出完了整个页面的时间也差不多就这么多
    而Repeater却有1秒时间在其他地方,或者是绑定前 ,也或者是绑定后。具体情况也不清楚...
      

  3.   

    说百了就是html控件和服务器控件的差别把,只能说在什么条件下用什么,不可能说为了效率既然有了C++还出Java和C#干什么。Repeater做了封装,这样基本不用什么代码就能实现形式数据,你说的Literal感觉象在用asp一样
      

  4.   

    觉得两者没什么可比性  Literal就是单纯向页面呈现字符,html不包含控件本身内部的处理逻辑
    Repeater内部要执行循环,解析子控件等等等等 更何况LZ的代码使用反射绑定数据,绑定过程也要耗时... 
     
    记得坛子里有篇RPT 和 DG对比的帖子来着
      

  5.   

    其实主要的性能损耗在这里:
    DataBinder.Eval(Container.DataItem, "ID")除掉这个性能损耗,其实双方差不多。Repeater虽然需要多执行一些代码,但与数据库操作比起来毕竟是小头。Repeater能让程序结构看起来更清晰,如前台写的数据绑定。
      

  6.   

    那也就是asp.net的思想就是通过牺牲了点性能来提高开发速度。减少代码。易于维护. 对吧
      

  7.   

    那也就是asp.net的思想就是通过牺牲了点性能来提高开发速度。减少代码。易于维护. 对吧
    倒也不能这样说,因为实际上性能损耗在DataBinder.Eval上,微软也建议你不要这样写。
    为了开发效率性能损耗是必然的,关键是损耗的程度,另外自己要清楚哪些地方存在性能损耗,不能把微软的东西拿来就用。
      

  8.   

    是吗,DataBinder.Eval很损耗吗?
    那请问下如何写才不损耗呢