我的页面模板算法

/// <summary>
    /// 根据模板,使用此法分析的方法输出字符串
    /// </summary>
    /// <param name="template"></param>
    /// <param name="dt"></param>
    /// <returns></returns>
    public static string Render(string template, DataTable dt)
    {
        StringBuilder sb = new StringBuilder(1000);
        List<string> arr = new List<string>();
        List<string> columns = new List<string>();
        int previousEndIndex = 0;

        //找到{xxx}
        int startIndex = template.IndexOf('{');
        int endIndex = template.IndexOf('}');

        while (startIndex != -1)
        {
            //存储上一个}和现在搜索到的{之间的字符串,如果是第一次搜索到{,那么previousEndIndex=0则存储的是字符串起始到第一个{之间的字符串
            arr.Add(template.Substring(previousEndIndex, startIndex - previousEndIndex));
            //存储列名
            columns.Add(template.Substring(startIndex + 1, endIndex - startIndex - 1));

            startIndex++;
            endIndex++;
            previousEndIndex = endIndex;

            startIndex = template.IndexOf('{', startIndex);
            endIndex = template.IndexOf('}', endIndex);
        }

        //如果模板不是以}结尾,说明后面还有字符串
        if (previousEndIndex < template.Length)
        {
            arr.Add(template.Substring(previousEndIndex));
        }
        //方法执行到此处,arr.Length==columns.Length或者arr.Length==columns.Length+1
       
        int i;
        foreach (DataRow row in dt.Rows)
        {
            i = 0;
            for (; i < columns.Count; i++)
            {
                sb.Append(arr[i]);                
                sb.Append(row[columns[i]].ToString());
            }
            if (i < arr.Count)
            {
                sb.Append(arr[i]);
            }
            
        }
        return sb.ToString();
    }

    /// <summary>
    /// 根据模板,使用正则匹配然后替换输出字符串
    /// </summary>
    /// <param name="template"></param>
    /// <param name="dt"></param>
    /// <returns></returns>
    public static string RenderTemplate(string template, DataTable dt)
    {
        StringBuilder sb = new StringBuilder(1000);
        MatchCollection matches = reg.Matches(template);
        string rowStr = template;
        foreach (DataRow row in dt.Rows)
        {
            rowStr = template;
            foreach (Match match in matches)
            {
                rowStr = rowStr.Replace(match.Value, row[match.Groups[1].Value].ToString());
            }
            sb.Append(rowStr);
            sb.Append("\n");
        }
        return sb.ToString();

    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

create table  links
(
    siteurl varchar(100),
    sitename varchar(100)
)
declare @i int
set @i=0
while(@i<100000)
begin
    insert links values('http://www.baidu.com','百度')
    set @i=@i+1
end

第一种:
后台代码如下:
public override void ProcessRequest(HttpContext context)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            base.ProcessRequest(context);
            watch.Stop();
            HttpContext.Current.Response.Write(watch.Elapsed.ToString());
        }
        protected void Page_Load(object sender, EventArgs e)
        {          
            if (!IsPostBack)
            {

                rpt.DataSource = GetTable();
                rpt.DataBind();

            }
        }

        public DataTable GetTable()
        {
            using (SqlConnection conn = new SqlConnection("Data Source=wh189\\sqlexpress;Initial Catalog=A;User ID=sa;Password=sa"))
            {
                DataTable dt = new DataTable();
                SqlDataAdapter sda = new SqlDataAdapter("select top 50000 * from dbo.links", conn);
                sda.Fill(dt);
                return dt;
            }
        }

前台代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestWeb._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div style="display: none;">
        <asp:Repeater ID="rpt" runat="server">
            <ItemTemplate>
                <a href='<%# ((System.Data.DataRowView)Container.DataItem)["siteurl"] %>'>
                    <%#  ((System.Data.DataRowView)Container.DataItem)["sitename"]%></a>
            </ItemTemplate>
        </asp:Repeater>        
    </div>
    <asp:Button ID="Button1" runat="server" Text="Button" />
    </form>
</body>
</html>

时间大概为1秒左右,如果没有使用System.Data.DataRowView,使用Eval,则时间大概在1.2秒左右


第二种:
前台代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestWeb._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div style="display: none;">       
        <%System.Data.DataTable dt = GetTable();
          foreach (System.Data.DataRow dr in dt.Rows)
          { %>
        <a href='<%=dr["siteurl"] %>'>
            <%=dr["sitename"]%></a>
        <%}
        %>
    </div>
    <asp:Button ID="Button1" runat="server" Text="Button" />
    </form>
</body>
</html>

后台代码如下:
 public override void ProcessRequest(HttpContext context)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            base.ProcessRequest(context);
            watch.Stop();
            HttpContext.Current.Response.Write(watch.Elapsed.ToString());
        }
        protected void Page_Load(object sender, EventArgs e)
        {
          
        }

        public DataTable GetTable()
        {
            using (SqlConnection conn = new SqlConnection("Data Source=wh189\\sqlexpress;Initial Catalog=A;User ID=sa;Password=sa"))
            {
                DataTable dt = new DataTable();
                SqlDataAdapter sda = new SqlDataAdapter("select top 50000 * from dbo.links", conn);
                sda.Fill(dt);
                return dt;
            }
        }
时间大概为0.2秒左右


第三种:
前台代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestWeb._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div style="display:none;">
        <%=Tool.Render("<a href='{siteurl}'>{sitename}</a>",GetTable()) %>    
    </div>
    <asp:Button ID="Button1" runat="server" Text="Button" />
    </form>
</body>
</html>


后台代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Collections;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;

namespace TestWeb
{
    public partial class _Default : System.Web.UI.Page
    {
        public override void ProcessRequest(HttpContext context)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            base.ProcessRequest(context);
            watch.Stop();
            HttpContext.Current.Response.Write(watch.Elapsed.ToString());
        }
        protected void Page_Load(object sender, EventArgs e)
        {
          
        }

        public DataTable GetTable()
        {
            using (SqlConnection conn = new SqlConnection("Data Source=wh189\\sqlexpress;Initial Catalog=A;User ID=sa;Password=sa"))
            {
                DataTable dt = new DataTable();
                SqlDataAdapter sda = new SqlDataAdapter("select top 50000 * from dbo.links", conn);
                sda.Fill(dt);
                return dt;
            }
        }
    }
}




/// <summary>
///Tool 的摘要说明
/// </summary>
public class Tool
{
    

    /// <summary>
    /// 根据模板,使用此法分析的方法输出字符串
    /// </summary>
    /// <param name="template"></param>
    /// <param name="dt"></param>
    /// <returns></returns>
    public static string Render(string template, DataTable dt)
    {
        StringBuilder sb = new StringBuilder(1000);
        List<string> arr = new List<string>();
        List<string> columns = new List<string>();
        int previousEndIndex = 0;

        //找到{xxx}
        int startIndex = template.IndexOf('{');
        int endIndex = template.IndexOf('}');

        while (startIndex != -1)
        {
            //存储上一个}和现在搜索到的{之间的字符串,如果是第一次搜索到{,那么previousEndIndex=0则存储的是字符串起始到第一个{之间的字符串
            arr.Add(template.Substring(previousEndIndex, startIndex - previousEndIndex));
            //存储列名
            columns.Add(template.Substring(startIndex + 1, endIndex - startIndex - 1));

            startIndex++;
            endIndex++;
            previousEndIndex = endIndex;

            startIndex = template.IndexOf('{', startIndex);
            endIndex = template.IndexOf('}', endIndex);
        }

        //如果模板不是以}结尾,说明后面还有字符串
        if (previousEndIndex < template.Length)
        {
            arr.Add(template.Substring(previousEndIndex));
        }
        //方法执行到此处,arr.Length==columns.Length或者arr.Length==columns.Length+1

        int i;
        foreach (DataRow row in dt.Rows)
        {
            i = 0;
            for (; i < columns.Count; i++)
            {
                sb.Append(arr[i]);
                sb.Append(row[columns[i]].ToString());
            }
            if (i < arr.Count)
            {
                sb.Append(arr[i]);
            }
        }
        return sb.ToString();
    }

    
}
时间大概也为0.2秒左右


如果把查询数据量增加到10万,发现第二种方法比第三种要快几秒 。但是如果将第三种方法中的Render方法做如下改进,则两者速度又差不多了:

public static string Render(string template, DataTable dt)
    {
    //使用HttpResponse 直接输出,而不使用StringBuilder
        HttpResponse res = HttpContext.Current.Response;
        
        List<string> arr = new List<string>();
        List<string> columns = new List<string>();
        int previousEndIndex = 0;

        //找到{xxx}
        int startIndex = template.IndexOf('{');
        int endIndex = template.IndexOf('}');

        while (startIndex != -1)
        {
            //存储上一个}和现在搜索到的{之间的字符串,如果是第一次搜索到{,那么previousEndIndex=0则存储的是字符串起始到第一个{之间的字符串
            arr.Add(template.Substring(previousEndIndex, startIndex - previousEndIndex));
            //存储列名
            columns.Add(template.Substring(startIndex + 1, endIndex - startIndex - 1));

            startIndex++;
            endIndex++;
            previousEndIndex = endIndex;

            startIndex = template.IndexOf('{', startIndex);
            endIndex = template.IndexOf('}', endIndex);
        }

        //如果模板不是以}结尾,说明后面还有字符串
        if (previousEndIndex < template.Length)
        {
            arr.Add(template.Substring(previousEndIndex));
        }
        //方法执行到此处,arr.Length==columns.Length或者arr.Length==columns.Length+1

        int i;
        foreach (DataRow row in dt.Rows)
        {
            i = 0;
            for (; i < columns.Count; i++)
            {
                res.Write(arr[i]);
                res.Write(row[columns[i]].ToString());
            }
            if (i < arr.Count)
            {
                res.Write(arr[i]);
            }
        }
        return "";
    } 

 

posted @ 2010-10-21 21:39  再快一点  阅读(335)  评论(0编辑  收藏  举报