首页 新闻 赞助 找找看

你能让这段代码飞快的运行起来吗?来吧,让改变发生......

0
悬赏园豆:100 [已解决问题] 解决于 2013-03-25 11:09

本人菜鸟一只,但是我并不甘心做菜鸟,想通过一切可能的方式获得学习方法和指引。
这是一段加载树形菜单的代码,运行效率......嗯~ 很低!加载需要很长时间,有时候还会报错。

但是作为菜鸟的我不知道如何优化,这让我灰常伤心。
但是我觉得这必定也是我学习提高的机会,博客园久闻大名,也常常逛。
今天斗胆撒出自己的问题。 希望获高人指点:贴出优化方式,
指出代码中的问题(命名写法不规范,思路很低级【低级在哪儿】,
格子没对齐,不管是什么方面的意见,只要是对程序员的要求我都希望听到并学习改正),
给出您的建议,告诉我您是怎么思考的,这些思考使用什么知识做支撑的等等等等。

根据选择的设备类型执行加载代码(调用User_ShowTree方法):

View Code
  1         /// <summary>
  2         /// 根据设备类别显示设备及部件树
  3         /// </summary>
  4         /// <param name="s_Origin"></param>
  5         /// <returns></returns>
  6         private bool User_ShowTree(string s_Origin)
  7         {
  8             #region 获得类实例
  9             C_DataSb_Device User_DataSb_Device = (C_DataSb_Device)GetObject("C_DataSb_Device");
 10             C_DAOSb_Device User_DAOSb_Device = (C_DAOSb_Device)GetObject("C_DAOSb_Device");
 11             C_DataPb_Code User_DataPb_Code = (C_DataPb_Code)GetObject("C_DataPb_Code");
 12             C_DAOPb_Code User_DAOPb_Code = (C_DAOPb_Code)GetObject("C_DAOPb_Code");
 13             #endregion
 14 
 15             string s_Module = "";//设备型号
 16             try
 17             {
 18                 #region 获得对应的设备类型,不选择则查询获得所有设备类型
 19                 if (this.Ddl_Type.SelectedValue != "")
 20                 {
 21                     User_DataPb_Code.setPCD_Code(this.Ddl_Type.SelectedValue);
 22                     User_DataPb_Code.setPCD_Type("731");
 23                     this.beginQuery(User_DAOPb_Code.Detail_QueryByTypeAndCode(User_DataPb_Code));
 24                 }
 25                 else
 26                 {
 27                     this.beginQuery(User_DAOPb_Code.Detail_QueryByType("731"));
 28                 }
 29                 ArrayList list = (ArrayList)this.queryForList();
 30                 #endregion
 31 
 32                 if (list.Count > 0)
 33                 {
 34                     s_Content.Append("<script type=\"text/javascript\">"); //拼接生成dTree
 35                     s_Content.Append("d = new dTree('d');");
 36 
 37                     //类型循环 第一层循环 1 
 38                     for (int k = 0; k < list.Count; k++)
 39                     {
 40                         if (s_Origin == "1" || s_Origin == "5")
 41                         {
 42                             s_Content.Append("d.add('" + ((C_DataPb_Code)list[k]).getPCD_Code() + "',-1,'" + ((C_DataPb_Code)list[k]).getPCD_Name() + "','top.Main.Right.location=\"../Sb_Jb/Sb_Jb_BaseManage.aspx?Type=" + ((C_DataPb_Code)list[k]).getPCD_Code() + "\"');");
 43                         }
 44                         else
 45                         {
 46                             s_Content.Append("d.add('" + ((C_DataPb_Code)list[k]).getPCD_Code() + "',-1,'" + ((C_DataPb_Code)list[k]).getPCD_Name() + "','');");
 47                         }
 48 
 49                         this.beginQuery(User_DAOSb_Device.Base_QueryByType(((C_DataPb_Code)list[k]).getPCD_Code())); //根据设备类型查询对应类型下的设备信息
 50                         DataSet Dts_Result = (DataSet)this.queryForDataSet(); //存储查询结果
 51                          
 52                         if (Dts_Result != null)
 53                         {
 54                             //对应类型下设备信息循环 
 55                             for (int i = 0; i < Dts_Result.Tables[0].Rows.Count; i++)
 56                             {
 57                                 s_Content.Append("d.add('" + Dts_Result.Tables[0].Rows[i][User_DataSb_Device.Col_SDB_ID].ToString() + "','" + ((C_DataPb_Code)list[k]).getPCD_Code() + "','" + Dts_Result.Tables[0].Rows[i][User_DataSb_Device.Col_SDB_Name].ToString() + "','JsEvent(\"" + Dts_Result.Tables[0].Rows[i][User_DataSb_Device.Col_SDB_ID].ToString() + "\",\"" + Dts_Result.Tables[0].Rows[i][User_DataSb_Device.Col_SDB_Name].ToString() + "\",\"\",\"\",\"" + s_Origin + "\",\"\",\"\")');");
 58 
 59                                 //查询设备第一层部件,即筛选出SDD_Parent字段为空的记录
 60                                 User_DataSb_Device.setSDD_Device(Dts_Result.Tables[0].Rows[i][User_DataSb_Device.Col_SDB_ID].ToString());
 61                                 User_DataSb_Device.setSDD_Parent("");
 62                                 User_DataSb_Device.setSDD_Type("101");  //只筛选指定设备部位部件
 63 
 64                                 if (s_Origin == "3")
 65                                 {
 66                                     User_DataSb_Device.setSDD_IsCorrect("1"); //只筛选需定检部位
 67                                 }
 68 
 69                                 //查询获得对应的设备部件
 70                                 this.beginQuery(User_DAOSb_Device.Detail_QueryByCondition(User_DataSb_Device));
 71                                 //存储查询结果
 72                                 DataTable Dtb_Detail = ((DataSet)this.queryForDataSet()).Tables[0];
 73 
 74                                 //对应设备下第一层部件信息循环 
 75                                 for (int j = 0; j < Dtb_Detail.Rows.Count; j++)
 76                                 {
 77                                     s_Module = "";
 78                                     if (Dtb_Detail.Rows[j][User_DataSb_Device.Col_SDD_Model].ToString() != "")
 79                                     {
 80                                         s_Module = "_" + Dtb_Detail.Rows[j][User_DataSb_Device.Col_SDD_Model].ToString();
 81                                     }
 82                                     //拼接菜单JS
 83                                     s_Content.Append("d.add('" + Dtb_Detail.Rows[j][User_DataSb_Device.Col_SDD_ID].ToString() + "','" + Dts_Result.Tables[0].Rows[i][User_DataSb_Device.Col_SDB_ID].ToString() + "','" + Dtb_Detail.Rows[j][User_DataSb_Device.Col_SDD_Name].ToString() + s_Module + "','JsEvent(\"" + Dts_Result.Tables[0].Rows[i][User_DataSb_Device.Col_SDB_ID].ToString() + "\",\"" + Dts_Result.Tables[0].Rows[i][User_DataSb_Device.Col_SDB_Name].ToString() + "\",\"\",\"\",\"" + s_Origin + "\",\"" + Dtb_Detail.Rows[j][User_DataSb_Device.Col_SDD_ID].ToString() + "\",\"" + Dtb_Detail.Rows[j][User_DataSb_Device.Col_SDD_Name].ToString() + "\")','','','','');");
 84                                     //继续循环往下筛选更多部件信息
 85                                     User_GetChildren(Dts_Result.Tables[0].Rows[i][User_DataSb_Device.Col_SDB_ID].ToString(), Dts_Result.Tables[0].Rows[i][User_DataSb_Device.Col_SDB_Name].ToString(), Dtb_Detail.Rows[j][User_DataSb_Device.Col_SDD_ID].ToString(), Dtb_Detail.Rows[j][User_DataSb_Device.Col_SDD_Name].ToString(), s_Origin, s_Content);
 86 
 87                                 }
 88                             }
 89                         }
 90                     }
 91                 }
 92                 else
 93                 {
 94                     base.MessageBox_Open("设备类型未设置,请联系管理员");
 95                     return false;
 96                 }
 97             }
 98             catch (Exception ex)
 99             {
100                 base.setWrong(ex.Message);
101                 return false;
102             }
103             s_Content.Append("document.write(d);");
104             s_Content.Append("</script> ");
105             return true;
106         }
107 
108         /// <summary>
109         /// 获取部件节点信息
110         /// </summary>
111         /// <param name="s_Device"></param>
112         /// <param name="s_DeviceName"></param>
113         /// <param name="s_Parent"></param>
114         /// <param name="s_ParentName"></param>
115         /// <param name="s_Origin"></param>
116         /// <param name="s_Content"></param>
117         private void User_GetChildren(string s_Device, string s_DeviceName, string s_Parent, string s_ParentName, string s_Origin, StringBuilder s_Content)
118         {
119             #region 获取类实例,赋值筛选条件
120             C_DataSb_Device User_DataSb_Device = (C_DataSb_Device)GetObject("C_DataSb_Device");
121             C_DAOSb_Device User_DAOSb_Device = (C_DAOSb_Device)GetObject("C_DAOSb_Device");
122 
123             User_DataSb_Device.setSDD_Device(s_Device);
124             User_DataSb_Device.setSDD_Parent(s_Parent);
125             User_DataSb_Device.setSDD_Type("101");  //只筛选指定部位的设备部件
126 
127             if (s_Origin == "3")
128             {
129                 User_DataSb_Device.setSDD_IsCorrect("1"); //只筛选需定检部位
130             }
131             #endregion
132 
133             string s_Module = "";//部件型号
134             try
135             {
136                 //查询某节点下的子节点信息(即查询某设备部件包含的明细部件信息)
137                 this.beginQuery(User_DAOSb_Device.Detail_QueryByDeviceAndParent(User_DataSb_Device));
138                 DataTable Dtb_Detail = ((DataSet)this.queryForDataSet()).Tables[0];
139 
140                 //循环查询结果
141                 for (int i = 0; i < Dtb_Detail.Rows.Count; i++)
142                 {
143                     s_Module = "";
144                     if (Dtb_Detail.Rows[i][User_DataSb_Device.Col_SDD_Model].ToString() != "")
145                     {
146                         s_Module = "_" + Dtb_Detail.Rows[i][User_DataSb_Device.Col_SDD_Model].ToString();
147                     }
148                     s_Content.Append("d.add('" + Dtb_Detail.Rows[i][User_DataSb_Device.Col_SDD_ID].ToString() + "','" + s_Parent + "','" + Dtb_Detail.Rows[i][User_DataSb_Device.Col_SDD_Name].ToString() + s_Module + "','JsEvent(\"" + s_Device + "\",\"" + s_DeviceName + "\",\"" + s_Parent + "\",\"" + s_ParentName + "\",\"" + s_Origin + "\",\"" + Dtb_Detail.Rows[i][User_DataSb_Device.Col_SDD_ID].ToString() + "\",\"" + Dtb_Detail.Rows[i][User_DataSb_Device.Col_SDD_Name].ToString() + "\")','','','','');");
149 
150                     User_GetChildren(s_Device, s_DeviceName, Dtb_Detail.Rows[i][User_DataSb_Device.Col_SDD_ID].ToString(), Dtb_Detail.Rows[i][User_DataSb_Device.Col_SDD_Name].ToString(), s_Origin, s_Content);
151                 }
152 
153             }
154             catch (Exception ex)
155             {
156                 base.setWrong(ex.Message);
157                 return;
158             }
159         }
三年二班的主页 三年二班 | 初学一级 | 园豆:5
提问于:2013-03-01 10:06
< >
分享
最佳答案
1

queryForDataSet  这个方法是做什么的呢.?是读取数据库么.?或是读配置文件.?

如果是的话.这里应该是一个可优化的地方,多次循环读库,会造成效率问题,

建议你一次把数据都读到内容里,然后再从内存里做筛选操作

还有就是,请不要用弱类型来操作数据,会造成多次装箱拆箱,也会影响效率.

收获园豆:40
只会造轮子 | 老鸟四级 |园豆:2274 | 2013-03-01 11:35

是查询方法 用的iBATIS

三年二班 | 园豆:5 (初学一级) | 2013-03-01 11:39

@三年二班: 建议你减少与数据库交互的次数,

一次性读出所有所需要显示的数据,

然后在内存里处理数据,显示到窗口上,

尽量减少内与数据库交互次数

 

我的QQ

hh-jm19890727@163.com如果不明白.再问我.

 

只会造轮子 | 园豆:2274 (老鸟四级) | 2013-03-01 16:20

@发粪图墙: 感谢你的回答 根据你的建议已经做了优化 谢谢

三年二班 | 园豆:5 (初学一级) | 2013-03-25 11:10
其他回答(4)
0

1、不展开全部子节点

2、如果必须展开全部子节点,起一个事务,全部查询完成后,关闭事务。

收获园豆:20
丑锉穷的软件工人 | 园豆:247 (菜鸟二级) | 2013-03-01 14:56
0

树形的结构显示时最好不展开下层,点+号再插入下一层,查找符合当前节点的子节点,顺序插入

生成树结构可以尝试递归方法,需要展开的数据全部加载,从root开始循环,递归方法插入子孙节点

收获园豆:20
-笨笨- | 园豆:240 (菜鸟二级) | 2013-03-03 09:42
0

没有仔细看,

1楼说的挺好的,是否有在递归里做数据库查询。 这样确实会很慢。

sep_09 | 园豆:202 (菜鸟二级) | 2013-03-04 11:54
0

问题分析:

     stack overflow, at line: 657

     这个说明 栈溢出了, 检查行 657代码.

     看代码, 最可能的原因:  User_GetChildren()中存在递归调用,  如果某中条件下陷入循环死递归,

     则这种情况必然触发栈溢出.

     请检查 递归部分是否存在逻辑漏洞, 会限制循环递归.    

 

主要问题:

     1.  User_GetChildren()中存在 可能不够安全(死循环)的 递归调用.  

     2.  sql访问次数太多.

              User_ShowTree()中 有三重循环,  做太多次sql操作了.

              需要优化.

收获园豆:20
smartfish_liu | 园豆:220 (菜鸟二级) | 2013-03-07 10:26
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册