我用了一个Hashtable来存储从数据库中取的数据,Hashtable取得的数据格式如下:
1042|2004-9-4 11:30:09,0,0,3608;2004-9-4 12:30:17,0,0,3605;2004-9-4 13:30:22,0,0,3610;2004-9-4 14:30:32,0,0,3608;2004-9-4 15:30:40,1,0,3145;2004-9-4 16:23:05,0,0,12;2004-9-4 16:23:17,0,0,4000;2004-9-4 17:30:07,0,0,3615;2004-9-4 18:30:22,1,0,2591;2004-9-4 19:13:33,0,0,11;2004-9-4 19:13:44,0,0,4000;2004-9-4 20:30:04,0,0,3611;2004-9-4 21:30:15,1,0,1918;2004-9-4 22:02:13,0,0,11;2004-9-4 22:02:24,0,0,4000;2004-9-4 23:30:09,0,0,3605;1040|2004-9-4 8:59:11,1,0,3499;2004-9-4 11:30:09,0,0,3608;2004-9-4 12:30:17,0,0,3605;2004-9-4 13:30:22,0,0,3610;2004-9-4 14:30:32,0,0,3608;2004-9-4 15:30:40,1,0,3145;2004-9-4 16:23:05,0,0,12;2004-9-4 16:23:17,0,0,4000;2004-9-4 17:30:07,0,0,3615;2004-9-4 18:30:22,1,0,164;2004-9-4 18:33:06,0,0,11;1046|2004-9-4 8:59:11,1,0,3499;2004-9-4 9:57:30,0,0,12;2004-9-4 9:57:42,0,0,4000;2004-9-4 11:30:09,0,0,3608;2004-9-4 12:30:17,0,0,3605;2004-9-4 13:30:22,0,0,3610;2004-9-4 14:30:32,0,0,3608;2004-9-4 15:30:40,1,0,3145;2004-9-4 16:23:05,0,0,12;2004-9-4 16:23:17,0,0,4000;2004-9-4 17:30:07,0,0,3615;2004-9-4 18:30:22,1,0,164;2004-9-4 18:33:06,0,0,11;2004-9-4 18:33:17,0,0,4000;2004-9-4 21:13:00,0,0,4000;2004-9-4 22:30:00,0,0,3609;2004-9-4 23:30:09,0,0,3605;1041|2004-9-4 11:30:09,1,0,3608;2004-9-4 12:30:17,1,0,3605;2004-9-4 13:30:22,0,0,157;2004-9-4 13:32:59,1,0,775;2004-9-4 13:45:54,1,0,4000;2004-9-4 15:30:09,0,0,3176;2004-9-4 16:23:05,1,0,12;2004-9-4 16:23:17,1,0,4000;2004-9-4 17:30:07,1,0,3615;2004-9-4 18:30:22,0,0,1206;2004-9-4 18:50:28,1,0,365;2004-9-4 18:56:33,0,0,1020;
“|”符号前面的是键,后面的是键对应的值,这些数据只是很小很小的一部分,值分为2004-9-4 11:30:09,0,0,3608;
分别指的是:上传时间,值,状态,持续时间;
再用1天中每隔1分钟的时间DateTime,例如:2004-9-4 00:01:00,2004-9-4 00:02:00(一次类推)和Hashtable中的上传时间+持续时间得到的DateTime进行比较,在持续时间内就输出。其实要完成的功能我都实现了的,只是打开网页的速度非常的慢,大概要执行8-10分钟才能执行出来,我就想问问大家,是不是我的方法太笨还是什么,还是在和Hashtable中数据进行比较的时候速度太慢,如果是这样,用什么来代替Hashtable呢?
反正数据量就是特别的大,有什么方法改进能使速度提高,请高手指教!

解决方案 »

  1.   

    ...
    你的value是string类型吧?
    你那么长的string,拼的时候就已经相当耗时了
    所以建议你写个结构体(struct)存到value里,这样你取也方便 
      

  2.   

    数据量特别大是指数据库中的量大,还是读到Hashtable表中的数据量大?要是读到Hashtable表中的数据量大,建议分批读取,每次读取少点。另外代码里是不是有循环?优化一下代码吧。或者把你的代码贴出来让高手优化啊。
      

  3.   

    补充一点,2005以后提供了泛型,你用hashtable是存的object,有拆装箱的性能损耗!
    建议用泛型List<TKey,TValue>或者Dictionary<TKey,TValue>
      

  4.   

    如果你的数据量很大的话,用hashtable效率还是不够高的。
      

  5.   

    如果Hashtable里的内容不经常变化的话,也可以考虑放进全局Cache里吧。
      

  6.   

    怎么能不慢呢?
    你用你的设计思路来想。
    假设你HASHTABLE里有N条数据。
    那么你就是1440(每天的分钟数)与N嵌套循环。
    如果非要这样,把你循环帖出来,我们尽量帮你优化语句执行效率吧,不过肯定改善是很有限的。
      

  7.   

    楼主吧代码贴一下吧,特别是循环的那个环节,Hashtable本身效率不是很好,建议楼主用泛型试试吧
      

  8.   

    使用泛型的dictionary<>,也许会好点
      

  9.   

     用泛化类型 不知道 速度会不会快一点呢 LIst<对象名>
      

  10.   

    存数据到Hashtable:public Hashtable getHashtable()
        {
            Hashtable HasList = new Hashtable();//用来保存指定煤矿传感器的信息
            try
            {
                string sQuerySql = "select SensorNum,TimeVal,RTData,RTStatus,ValidTime from RealTimeHistory where MineNum='" + strKBH + "' and TimeVal>='" + strDate + " 00:00:00' and TimeVal<='" + strDate + " 23:59:59' order by TimeVal";
                conn.open();
                DataSet myQueryDs = conn.ExceDS(sQuerySql);
                conn.close();
                for (int j = 0; j < myQueryDs.Tables[0].Rows.Count; j++)
                {
                    string s1 = myQueryDs.Tables[0].Rows[j][1].ToString().Trim();
                    string s2 = myQueryDs.Tables[0].Rows[j][2].ToString().Trim();
                    string s3 = myQueryDs.Tables[0].Rows[j][3].ToString().Trim();
                    string s4 = myQueryDs.Tables[0].Rows[j][4].ToString().Trim();
                    ArrayList list1 = new ArrayList();
                    list1.Add(s1);
                    list1.Add(s2);
                    list1.Add(s3);
                    list1.Add(s4);
                    string strKey = myQueryDs.Tables[0].Rows[j][0].ToString().Trim();
                    if (HasList.ContainsKey(strKey))
                    {
                        ArrayList list3 = (ArrayList)HasList[strKey];
                        list3.Add(list1);
                        HasList.Remove(strKey);
                        HasList.Add(strKey, list3);
                    }
                    else
                    {
                        ArrayList list2 = new ArrayList();
                        list2.Add(list1);
                        HasList.Add(strKey, list2);
                    }
                }
            }
            catch (Exception em)
            {
                Response.Write(em.Message);
            }
            return HasList;
        }传入时间+持续时间(秒)的方法:public DateTime TimeAdd(string strNowTime,string sTime)
        {
            string sDate = string.Empty;
            DateTime getTime = new DateTime();
            DateTime nowTime = Convert.ToDateTime(strNowTime);
            TimeSpan a = new TimeSpan(nowTime.Ticks);
            TimeSpan t = new TimeSpan(Convert.ToInt64(sTime) * (1000 * 10000));
            TimeSpan ts = a.Add(t);
            int iDay = a.Days - ts.Days;
            if (iDay != 0)
            {
                bTime = true;//表示已经持续到了第二天
                sDate = nowTime.Year.ToString() + "-" + nowTime.Month.ToString() + "-" + nowTime.Day.ToString() + " " + ts.Hours.ToString() + ":" + ts.Minutes.ToString() + ":" + ts.Seconds.ToString();
            }
            else
            {
                bTime = false;
                sDate = nowTime.Year.ToString() + "-" + nowTime.Month.ToString() + "-" + nowTime.Day.ToString() + " " + ts.Hours.ToString() + ":" + ts.Minutes.ToString() + ":" + ts.Seconds.ToString();
            }
            getTime = Convert.ToDateTime(sDate);
            return getTime;
        }上面的执行速度我想不会带来很大的影响,下面的就是执行的关键,所谓的慢我断点测试过就是出现在下面的代码里,我是将最后的数据绑定到DataGrid控件里,所以数据慢就是在建立Datagrid控件的数据源时慢,代码如下:ICollection CreateDataSource()
        {
            try
            {
                DataRow dr;
                //
                //得到标头
                //
                dt.Columns.Add(new DataColumn("时间", typeof(string)));
                string strSql = "select distinct[SensorNum] from RealTimeHistory where MineNum='" + strKBH + "'";
                conn.open();
                DataSet myDs = conn.ExceDS(strSql);
                conn.close();
                for (int i = 0; i < myDs.Tables[0].Rows.Count; i++)
                {
                    listLie.Add(myDs.Tables[0].Rows[i][0].ToString().Trim());
                    try
                    {
                        string sSql = "select SensorName from Sensor where MineNum='" + strKBH + "' and SensorNum='" + myDs.Tables[0].Rows[i][0].ToString().Trim() + "'";
                        conn.open();
                        DataSet myDss = conn.ExceDS(sSql);
                        conn.close();
                        string sName = myDs.Tables[0].Rows[i][0].ToString().Trim() + "<br>" + myDss.Tables[0].Rows[0][0].ToString().Trim();
                        dt.Columns.Add(sName, typeof(string));
                    }
                    catch
                    {
                        string sName = myDs.Tables[0].Rows[i][0].ToString().Trim() + "<br>" + "未设置";
                        dt.Columns.Add(sName, typeof(string));
                    }
                }
                //
                //将查询指定日期范围内的数据存入Hashtable中
                //
                Hashtable HasList = this.getHashtable();            
                //
                //取出时间,然后和Hashtable比较取值
                //
                string sTimeSql = "select distinct(TimeVal) from RealTimeHistory where MineNum='" + strKBH + "' and  TimeVal>='" + strDate + " 00:00:00' and TimeVal<='" + strDate + " 23:59:59' order by TimeVal";
                conn.open();
                DataSet myTimeDs = conn.ExceDS(sTimeSql);
                conn.close();
                iHangNum = myTimeDs.Tables[0].Rows.Count;
                for (int x = 0; x < iHangNum; x++)
                {
                    dr = dt.NewRow();
                    string sT = myTimeDs.Tables[0].Rows[x][0].ToString().Trim();
                    dr[0] = sT;
                    for (int y = 0; y < listLie.Count; y++)
                    {
                        int iLie = y + 1;
                        string skey = listLie[y].ToString();
                        if (HasList.ContainsKey(skey))
                        {
                            ArrayList listA = (ArrayList)HasList[skey];
                            for (int i = 0; i < listA.Count; i++)
                            {
                                ArrayList listB = (ArrayList)listA[i];
                                DateTime timeA = Convert.ToDateTime(listB[0].ToString().Trim());
                                DateTime timeB = Convert.ToDateTime(myTimeDs.Tables[0].Rows[x][0].ToString().Trim());
                                DateTime thisTime = this.TimeAdd(listB[0].ToString().Trim(), listB[3].ToString().Trim());
                                if ((timeB >= timeA) && (timeB <= thisTime))
                                {
                                    if (bTime == true)
                                    {
                                        dr[iLie] = "0";
                                    }
                                    else
                                    {
                                        
                                        if (listB[1].ToString().Trim() == "0" && listB[2].ToString().Trim() == "0")
                                        {
                                            dr[iLie] = "关";
                                            break;
                                        }
                                        else if (listB[1].ToString().Trim() == "1" && listB[2].ToString().Trim() == "0")
                                        {
                                            dr[iLie] = "开";
                                            break;
                                        }
                                        else
                                        {
                                            dr[iLie] = listB[1].ToString().Trim();
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    dr[iLie] = "0";
                                }
                            }
                        }
                        else
                        {
                            dr[iLie] = "无";
                        }
                    }
                    dt.Rows.Add(dr);
                }
            }
            catch(Exception e)
            {
                Response.Write(e.Message);
            }
            DataView dv = new DataView(dt);
            return dv;
        }最后绑定DataGrid
      

  11.   


    HashTable 本身是适合存储小数据量的容器,如果需要8-10分钟才能加载完,建议还是仔细跟踪下代码块在哪执行比较慢,然后再找解决方案!(建议使用IList<>)
      

  12.   

    是循环中的处理和大量数据的转型装箱耗时
    可以用泛型字典类Dictionary<K,V>
      

  13.   

    IList <>   怎么用呀
      

  14.   

    这点东西 放到Dataset里面会快很多的  而其也容易取啊
      

  15.   

    没看明白你的逻辑是什么样的,为什么你不优化你的SQL语句让他们直接在数据库里比较完了再输出结果