效率狗的迷茫!改动一点节约了1分钟

  其实我是标题党,这篇文章并不是什么高端的优化教程,而是一个小菜鸡在生活中遇到的一个真实问题。

  最近在一个项目,项目中有一个需求是这样的,从文本文件中读取若干数据,这些数据是一条条通过UDP接收的数据包,每个包长度是1046个字节,其中第a,b,c个字节(连续的)代表一个标识码,UDP是由6个IP发出的,因为当初接收数据时,发送端已经运行了一段时间,所以表示码是从某一个特别大的值开始的,博主的任务是把其中的标识码改成从0开始,每次加2.。

  数据包可能出现错乱,比如连续出现了5个标识码为0016A5的数据包,突然出现了几个标识码为0016A7的数据包,再出现1个标识码为0016A5的数据包。要保证那个6个标识码为0016A5的全部被修改。

 

   博主面对是一个大于100MB的文件,读取出来大约有125000条数据,如果6个ip为一组,那就是近似20833组数据。

 

  博主的思路是这样的,用两层循环,外层循环 循环 125000/6次 内层循环理论循环125000次,设置一个变量,记录已经修改的个数,每次找到一个符合条件的数据包,变量+1,如果,已经找到6了 ,则跳出内层循环,变量清零。

//总共进行的比较操作次数 测试用
            //long CompareCount = 0;
            //long CompareCount2 = 0;

            
            int mm = datas[0].buffBytes.Length;
            int count = datas.Count;

            byte[] line1start = new byte[] {byte.Parse("0"),datas[0].buffBytes[10], datas[0].buffBytes[11], datas[0].buffBytes[12] };
            int intline1start = BitConvertHelper.ExtractToInt(line1start, 0);

            byte[] line2start = new byte[] {byte.Parse("0"), datas[0].buffBytes[526], datas[0].buffBytes[527],datas[0].buffBytes[528]};
            int intlin2start = BitConvertHelper.ExtractToInt(line2start, 0);
            //K等于6时跳出 减少循环次数
            int k = 0;
          
            //数据是连续的 还是断了
            bool _isCut = false;
            //测试用 进入的时间
            Console.WriteLine("开始的时间    " + DateTime.Now.ToString());
            //
            for (int i = 0; i < count/6; i++)
            {
               
                byte[] line1Bytes = BitConverter.GetBytes(line1);
                BitConvertHelper.ReverseBytes(line1Bytes);
                
                byte[] line2Bytes = BitConverter.GetBytes(line2);
                BitConvertHelper.ReverseBytes(line2Bytes);
                for (int j = 0; j < count; j++)
                {
                    //CompareCount++;//测试用、

                    if (datas[j].buffBytes[10] == line1start[1] && datas[j].buffBytes[11] == line1start[2] &&
                        datas[j].buffBytes[12] == line1start[3])
                    //if (datas[j].lineOne == intline1start)
                    {
                        for (int l = 0; l < 3; l++)
                        {
                            datas[j].buffBytes[10 + l] = line1Bytes[l + 1];
                            datas[j].buffBytes[526 + l] = line2Bytes[l + 1];

                        }
                        k = k + 1;

                        datas[j].lineOne = line1;
                    }
                  
                    if (k == 6)
                    {
                        //_isCut = false;
                        //一组6个数据更改 完毕 进入下一组
                        //CompareCount2++;
                        break;
                    }
                   

                    
                }
                k = 0;
                line1=line1+2;
                line2=line2+2;
                intline1start = intline1start + 2;
                intlin2start=intlin2start+2;
                line1start =
                    BitConvertHelper.ReverseBytes(BitConverter.GetBytes(intline1start));
               
                line2start =
                    BitConvertHelper.ReverseBytes(BitConverter.GetBytes(intline1start));
               

            }
            //测试用 结束的时间
            Console.WriteLine("结束的时间    "+DateTime.Now.ToString());
            //
            //Console.WriteLine(CompareCount+"     "+CompareCount2);


结果效率惨不忍睹,博主从没等到程序运行完成!

 

效率太差了!。

博主又对它进行了一些优化,比如增加一个变量,记录已经改变过得,连续的UDP包数量,这样内层循环就不用每次都从第0个开始了,但是并没有什么鸟用!!


 public  class Data
    {
       public byte[] buffBytes=new byte[1046];
       public byte[] LineOne=new byte[3];
       public int lineOne = 0;

    }

在第一读取时,就把表示位算出来,比较时只需要比较一次。

  //if (datas[j].buffBytes[10] == line1start[1] && datas[j].buffBytes[11] == line1start[2] &&
                    //    datas[j].buffBytes[12] == line1start[3])
                    if (datas[j].lineOne == intline1start)
                    {
                        for (int l = 0; l < 3; l++)
                        {
                            datas[j].buffBytes[10 + l] = line1Bytes[l + 1];
                            datas[j].buffBytes[526 + l] = line2Bytes[l + 1];

                        }
                        k = k + 1;

                        datas[j].lineOne = line1;
                    }
                  
                    if (k == 6)
                    {
                        //_isCut = false;
                        //一组6个数据更改 完毕 进入下一组
                        //CompareCount2++;
                        break;
                    }

结果博主活着等到了程序跑完的那一天~~



经检查数据都进行了修改,任务目的已经达到,但是1分钟还是太慢了。。。。

博主不知道是不是用字典会更快一点, 如果各位大大能提点意见 博主不胜感激!!

后来测试直接比较3位字节 耗时2分钟  也就是说我节约了1分钟





















后来 我把代码改成先按照IP分组,再每组同时修改!!这里应该考虑一下 丢线的问题

 List<DataBuffer>  datasList=new List<DataBuffer>();
            datasList = DataReader(path);


            Console.WriteLine("开始的时间    " + DateTime.Now.ToString());
            var q = from data1 in datasList group data1 by data1.Bytes[9];

            //Parallel.ForEach(q,d =>); 
            List<List<DataBuffer>> datalistsList = new List<List<DataBuffer>>();
            foreach (var g in q)
            {
                List<DataBuffer> datassList = new List<DataBuffer>();
                foreach (var b in g)
                {
                    datassList.Add(b);
                }
                datalistsList.Add(datassList);
            }
            for (int i = 0; i < datalistsList[0].Count; i++)
            {
                Parallel.ForEach(datalistsList, d => d[i].LineOne = d[i].LineOne - 6135);
            }
            Console.WriteLine(datasList[datasList.Count-1].LineOne);
            for (int i = 0; i < datasList.Count; i++)
            {
                byte[] line1Bytes =BitConvertHelper.ReverseBytes( BitConverter.GetBytes(datasList[i].LineOne));
                byte[] line2Bytes =BitConvertHelper.ReverseBytes( BitConverter.GetBytes(datasList[i].LineOne + 1));
                for (int l = 0; l < 3; l++)
                {
                    datasList[i].Bytes[10 + l] = line1Bytes[l + 1];
                    datasList[i].Bytes[526 + l] = line2Bytes[l + 1];
                }
            }


仅仅 用时 1s(没考虑丢线的问题)





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值