当前位置: 首页 > 科技观察

如何将前端代码速度提升60倍

时间:2023-03-22 12:02:43 科技观察

今天的问题从排序算法入手,讲解如何根据业务需求结合金典的算法实现js的高性能开发。场景老板让小明对公司20000+条数据进行排序,但是由于排序操作频繁发生,如果操作执行时间很慢,会严重降低用户体验。听到这个噩耗,小明开始码字了。1.一个没有违和感的排序算法小明根据需求想了想,写出了如下算法:/***maxsorting*@param{*}arr*耗时:760ms*/functionmaxSort(arr){让结果=[...arr];for(leti=0,len=result.length;i0;i--){for(让j=0;jarr[j+1]){swap(arr,j,j+1);}}}返回arr;}测试完用了377ms,完美,小明放到项目里测试,频繁排序还是有点卡,能优化一下吗?想了半天,小明完善了冒泡排序:/***使用索引优化后的冒泡排序*@param{Array}arr*耗时:350ms*/functionbubbleSort2(arr){leti=arr.length-1;while(i>0){让pos=0;for(letj=0;jarr[j+1]){pos=j;交换(arr,j,j+1);}}我=位置;}returnarr;}提高根据缓存索引位置排序的性能,节省时间20ms,但收获不大。小明开始和自己纠结,继续在维基百科上搜索,终于找到了一个方法:/***在每次排序时,进行两次正向和反向冒泡,*一次可以得到两个最终值(最大值和最小值),*从而减少了大约一半的外排序次数*@param{*}arr*耗时:312ms*/functionbubbleSort3(arr){letstart=0;让结束=arr.length-1;while(startarr[i+1]){endPos=i;(arr,i,i+1);}}end=endPos;for(leti=end;i>start;i--){if(arr[i-1]>arr[i]){startPos=i;交换(arr,我-1,我);}}开始=startPos;}返回arr;}通过每个排序分别进行两次正向和反向冒泡,小明减少了38ms的时间,不错~再次推荐大家有事上维基百科,总有适合你的。3.插入排序小规模成功后,小明膨胀了,他说要把排序时间降到100ms,于是后来又开发了如下算法:/***插入排序--基础版*@param{*}arr*耗时:897ms*/functioninsertionSort(arr){for(leti=1,len=arr.length;itemp){arr[preIndex+1]=arr[preIndex];preIndex-=1;}arr[preIndex+1]=temp;}返回arr;}897ms,小明不熟练的流下了眼泪。最后小明拿出这个看家本领,把二分查找找出来,最后把修改后的代码放到下面:@param{*}arr*@param{*}maxIndex*@param{*}value*/functionbinarySearch1(arr,maxIndex,value){letmin=0;让max=maxIndex;while(min<=max){constm=Math.floor((min+max)/2);如果(arr[m]<=值){min=m+1;}else{最大值=m-1;}}返回分钟;}/***使用二分法优化插入排序*@param{*}arr*耗时:86ms*/functioninsertionSort1(arr){for(leti=1,len=arr.length;i=insertIndex;preIndex--){arr[preIndex+1]=arr[preIndex];}arr[insertIndex]=temp;}returnarr;}完美,只用了86毫秒!小明兴奋地站了起来,甚至拍了拍桌子,完全不顾全场的目光。小明已经很满意了。他对86ms还算满意,老板也对他印象深刻。4.希尔排序没有改进的余地吗?经过调查研究,表明有更好的解决方案:/***希尔排序*核心:通过动态定义的间隙排序,先排序距离较小的Far元素,然后逐步推进*@param{*}arr*耗时:15ms*/functionshellSort(arr){constlen=arr.length;让gap=Math.floor(len/2);while(gap>0){//间隙距离for(leti=gap;itemp){arr[preIndex+gap]=arr[preIndex];preIndex-=差距;}arr[preIndex+gap]=temp;}gap=Math.floor(gap/2);}返回arr;5.归并排序/***归并排序*@param{*}arr*耗时30ms*/functionconcatSort(arr){constlen=arr.length;如果(len<2){返回arr;}constmid=Math.floor(len/2);constleft=arr.slice(0,mid);constright=arr.slice(mid);返回concat(concatSort(left),concatSort(right));}functionconcat(left,right){constresult=[];while(left.length>0&&right.length>0){result.push(left[0]<=right[0]?left.shift():right.shift());}returnresult.concat(left,right);}耗时30ms,我要优秀。有没有更快的方法?答案是肯定的,不过会涉及到比较高僧的数学知识,放弃吧,小子……

最新推荐
猜你喜欢