js for foreach 快慢_js基本搜索算法实现与170万条数据下的性能测试

5f2c49bfe3a537bcf776ea9a4d6f89b6.png

前言

今天让我们来继续聊一聊js算法,通过接下来的讲解,我们可以了解到搜索算法的基本实现以及各种实现方法的性能,进而发现for循环,forEach,While的性能差异,我们还会了解到如何通过web worker做算法分片,极大的提高算法的性能。

同时我还会简单介绍一下经典的二分算法,哈希表查找算法,但这些不是本章的重点,之后我会推出相应的文章详细介绍这些高级算法,感兴趣的朋友可以关注我的专栏,或一起探讨。

对于算法性能,我们还是会采用上一章《前端算法系列》如何让前端代码速度提高60倍中的getFnRunTime函数,大家感兴趣的可以查看学习,这里我就不做过多说明。

在上一章《前端算法系列》如何让前端代码速度提高60倍我们模拟了19000条数据,这章中为了让效果更明显,我将伪造170万条数据来测试,不过相信我,对js来说这不算啥。。。

1.for循环搜索

基本思路:通过for循环遍历数组,找出要搜索的值在数组中的索引,并将其推进新数组

代码实现如下:

const getFnRunTime = require('./getRuntime');/*** 普通算法-for循环版* @param {*} arr * 耗时:7-9ms*/function searchBy(arr, value) {let result = [];for(let i = 0, len = arr.length; i < len; i++) {if(arr[i] === value) {result.push(i);}}return result}getFnRunTime(searchBy, 6)

测试n次稳定后的结果如图:

75725f8bf28548a36474b96a40c8e7dd.png

2.forEach循环

基本思和和for循环类似:

/*** 普通算法-forEach循环版* @param {*} arr * 耗时:21-24ms*/function searchByForEach(arr, value) {let result = [];arr.forEach((item,i) => {if(item === value) {result.push(i);}})return result
}

耗时21-24毫秒,可见性能不如for循环(先暂且这么说哈,本质也是如此)。

3.while循环

代码如下:

/*** 普通算法-while循环版* @param {*} arr * 耗时:11ms*/function searchByWhile(arr, value) {let i = arr.length,result = [];while(i) {if(arr[i] === value) {result.push(i);}i--;}return result
}

可见while和for循环性能差不多,都很优秀,但也不是说forEach性能就不好,就不使用了。foreach相对于for循环,代码减少了,但是foreach依赖IEnumerable。在运行时效率低于for循环。但是在处理不确定循环次数的循环,或者循环次数需要计算的情况下,使用foreach比较方便。而且foreach的代码经过编译系统的代码优化后,和for循环的循环类似。

4.二分法搜索

二分法搜索更多的应用场景在数组中值唯一并且有序的数组中,这里就不比较它和for/while/forEach的性能了。

基本思路:从序列的中间位置开始比较,如果当前位置值等于要搜索的值,则查找成功;若要搜索的值小于当前位置值,则在数列的前半段中查找;若要搜索的值大于当前位置值则在数列的后半段中继续查找,直到找到为止

代码如下:

/*** 二分算法* @param {*} arr * @param {*} value */function binarySearch(arr, value) {let min = 0;let max = arr.length - 1;while (min <= max) {const mid = Math.floor((min + max) / 2);if (arr[mid] === value) {return mid;} else if (arr[mid] > value) {max = mid - 1;} else {min = mid + 1;}}return 'Not Found';}

在数据量很大的场景下,二分法效率很高,但不稳定,这也是其在大数据查询下的一点小小的劣势。

5.哈希表查找

哈希表查找又叫散列表查找,通过查找关键字不需要比较就可以获得需要记录的存储位置,它是通过在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)

哈希表查找的使用场景: 哈希表最适合的求解问题是查找与给定值相等的记录 哈希查找不适合同样的关键字对应多条记录的情况 * 不适合范围查找,比如查找年龄18~22岁的同学

在这我先给出一个最简版的hashTable,方便大家更容易的理解哈希散列:

/*** 散列表* 以下方法会出现数据覆盖的问题*/
function HashTable() {var table = [];// 散列函数var loseloseHashCode = function(key) {var hash = 0;for(var i=0; i<key.length; i++) {hash += key.charCodeAt(i);}return hash % 37};// putthis.put = function(key, value) {var position = loseloseHashCode(key);table[position] = value;}// getthis.get = function(key) {return table[loseloseHashCode(key)]}// removethis.remove = function(key) {table[loseloseHashCode(key)] = undefined;}
}

该方法可能会出现数据冲突的问题,不过也有解决方案,由于这里涉及的知识点比较多,后期我会专门推出一篇文章来介绍:

  • 开放定址法
  • 二次探测法
  • 随机探测法

使用web worker优化

通过以上的方法,我们已经知道各种算法的性能和应用场景了,我们在使用算法时,还可以通过web worker来优化,让程序并行处理,比如将一个大块数组拆分成多块,让web worker线程帮我们去处理计算结果,最后将结果合并,通过worker的事件机制传给浏览器,效果十分显著。

总结

  1. 对于复杂数组查询,for/while性能高于forEach等数组方法
  2. 二分查找法的O(logn)是一种十分高效的算法。不过它的缺陷也很明显:必须有序,我们很难保证我们的数组都是有序的。当然可以在构建数组的时候进行排序,可是又落到了第二个瓶颈上:它必须是数组。数组读取效率是O(1),可是它的插入和删除某个元素的效率却是O(n)。因而导致构建有序数组的时候会降低效率。
  3. 哈希表查找的基本用法及使用场景。
  4. 条件允许的话,我们可以用web worker来优化算法,让其在后台并行执行。

好啦,这篇文章虽然比较简单,但十分重要,希望大家对搜索算法有更加直观的认识,也希望大家有更好的方法,一起探讨交流。

接下来会推出更多优秀的算法,敬请期待哦~

最后,欢迎加入前端技术群,一起探讨前端的魅力

更多推荐

  • 如何快速掌握es6+新特性及核心语法?
  • 前端开发中79条不可忽视的知识点汇总
  • 15条前端必备的性能优化方法,你知道哪些
  • 如何用css3实现惊艳面试官的背景动画(高级附源码)?
  • 用webpack4.0撸单页/多页脚手架(jquery,react,vue,typescript)
  • 《javascript高级程序设计》核心知识总结
  • vue高级进阶系列——用typescript玩转vue和vuex

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/552014.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python获取工作日_Python获取一段日期内的工作日和所有日期

Pandas1、获取工作日&#xff1a;bdate_rangeimport pandas as pde pd.bdate_range(8/7/2019, 8/31/2019)e.date #获取日期列表array([datetime.date(2019, 8, 7), datetime.date(2019, 8, 8),datetime.date(2019, 8, 9), datetime.date(2019, 8, 12),datetime.date(2019, 8, …

iterm php,iTerm2笔记

本文是 iTerm2 的使用笔记&#xff0c;不定期更新。1 注释说明对于 Preferences 的修改&#xff0c;> 表示需要切换选项卡&#xff0c;-> 表示在同一选项卡内2 参考3 杂301 如何随时随地一键调用 Quake-like iTerm2首先声明&#xff1a;由于 Mac OS 本身对窗体「最大化」…

python 正则表达式 sub_python 正则表达式 re.sub re.subn

python正则表达式模块简介Python 自1.5版本起增加了re 模块&#xff0c;它提供 Perl 风格的正则表达式模式。Python 1.5之前版本则是通过 regex 模块提供 Emacs 风格的模式。Emacs 风格模式可读性稍差些&#xff0c;而且功能也不强&#xff0c;因此编写新代码时尽量不要再使用 …

清浊音判别 matlab,matlab语音信号处理如何判别清浊音?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼这是我一个学长给的程序&#xff0c;他说里面要算得基本上已经实现了改一下就可以用了。。。但是i本人不是主攻matlab的说白了就是不怎么会&#xff0c;&#xff0c;想问下该怎么改来实现判断清浊音的功能。%对语音信号采样分帧cle…

python upper_Python 3中的模块级string.upper函数在哪里?

如何让这段代码在3中运行&#xff1f; 请注意&#xff0c;我不是"foo".upper()在字符串实例级别询问。import string try: print("string module, upper function:") print(string.upper) foo string.upper("Foo") print("foo:%s" % …

python数据科学实践 常象宇_Python数据科学实践

章基于Python的数据科学环境搭建1.1Python是数据科学“大势所趋”1.2Anaconda入门——工欲善其事&#xff0c;必先利其器1.3JupyterNotebook入门1.4Markdown单元格的使用1.5Spyder入门1.6小结第2章Python基础2.1“火锅团购数据”简介2.2读写数据2.3Python数据类型与结构2.4控制…

matlab emd功率谱密度,【脑电信号分类】脑电信号提取PSD功率谱密度特征

脑电信号是一种非平稳的随机信号&#xff0c;一般而言随机信号的持续时间是无限长的&#xff0c;因此随机信号的总能量是无限的&#xff0c;而随机过程的任意一个样本函数都不满足绝对可积条件&#xff0c;所以其傅里叶变换不存在。不过&#xff0c;尽管随机信号的总能量是无限…

小甲鱼python课后题简书_Python练习题100道

1.有四个数字&#xff1a;1,2,3,4&#xff0c;能组成多少个互不相同且无重复数字的三位数&#xff1f;各是多少&#xff1f; 方法一&#xff1a;遍历所有可能&#xff0c;把重复的剃掉。 total0 for i in range(1,5): for j in range(1,5): for k in range(1,5): if((i!j)and(j…

决策算法python_GitHub - nxety/MachineLearning_Python: 机器学习算法python实现

机器学习算法Python实现目录1、代价函数其中&#xff1a;下面就是要求出theta&#xff0c;使代价最小&#xff0c;即代表我们拟合出来的方程距离真实值最近共有m条数据&#xff0c;其中代表我们要拟合出来的方程到真实值距离的平方&#xff0c;平方的原因是因为可能有负值&…

php7.1安装mysqli扩展,centos php7 安装mysqli扩展心得

在新配服务器时发现&#xff0c;php无法连接到mysql。通过phpinfo发现。根本没有显示mysqli的相关配置。经过一系列研究。总结了下。&#xff1a;第一步&#xff1a;在phpinfo里没有mysqli配置&#xff0c;原因是安装php7时没有configure mysqli安装php方法&#xff1a;wget ht…

组装服务器配置清单_2020年组装电脑配置清单列表

随着电脑技术的不断革新&#xff0c;越来越多的家庭都有各式各样的电子设备。而电脑现在基本上是家家都有的物品&#xff0c;可是在购买电脑的时候新手小白需要注意那些事项呢&#xff1f;今天我们就给告诉小白如何组装电脑以小白组装电脑配置清单。1、购买电脑&#xff0c;您首…

oracle 关于归档的视图,oracle 与归档日志相关的几个视图

归档日志占据的数据库举足轻重的位置&#xff0c;以下系统视图来了解归档日志情况V$ARCHIVEV$ARCHIVED_LOG 已归档日志详单V$ARCHIVE_GAP 归档日志丢失V$ARCHIVE_PROCESSES 归档进程信息V$ARCHIVE_DEST 查看备份路径情况V$ARCHIVE_DEST_STATUSv$recovery_f…

mysql python is not installed_最全的解决安装MySQL-Python出现的问题: pip install MySQl-Python 出现:下列问题...

问题 1&#xff1a;Microsoft Visual C 9.0 is required error: Microsoft Visual C 9.0 is required 在Windows下用pip安装MySQl-Python报如下错误&#xff0c;看错误提示就知道去http://aka.ms/vcpython27找解决方法了 error: Microsoft Visual C 9.0 is required (Unable to…

python旋转数组_Python3实现旋转数组的3种算法

一、试题给出一个数组&#xff0c;将数组中的元素往右边移动k个位置&#xff0c;当中k是非负数。比如说&#xff1a;输入:[1,2,3,4,5,6,7]和k3输出:[5,6,7,1,2,3,4]解释:往右边旋转1步:[7,1,2,3,4,5,6]往右边旋转2步:[6,7,1,2,3,4,5]往右边旋转3步:[5,6,7,1,2,3,4]*反映&#x…

python数字大小写转换代码_用python实现把数字人民币金额转换成大写的脚本程序...

# -*- coding: utf-8 -*- def Num2MoneyFormat( change_number ): """ .转换数字为大写货币格式( format_word.__len__() - 3 2位小数 ) change_number 支持 float, int, long, string """ format_word ["分", "角", &quo…

count数据库优化oracle,迷惑性SQL性能问题排查与优化

&#xff1a;数据科学、人工智能从业者的在线大学。数据科学(Python/R/Julia)数据分析、机器学习、深度学习作者简介戴秋龙&#xff0c;拥有超过八年的电信、保险、税务行业核心系统ORACLE数据库优化&#xff0c;优化经验&#xff0c;具备丰富的行业服务背景。对Oracle数据库有…

python getopt参数参数自动补全_如何在Python中使用getopt / OPTARG?如果给出过多的参数(9),如何转移参数?...

How to use getopt/optarg in Python?解决方案This is an example of how I do it, I usually use the same basic template:import sysimport getopttry:opts, args getopt.getopt(sys.argv[1:], m:p:h, [miner, params, help])except getopt.GetoptError:usage()sys.exit(2…

python读取数据库数据类型_Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】...

本文实例讲述了Python实现从SQL型数据库读写dataframe型数据的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a; Python的pandas包对表格化的数据处理能力很强&#xff0c;而SQL数据库的数据就是以表格的形式储存&#xff0c;因此经常将sql数据库里的数据直接读取为…

oracle客户端三种连接,客户端连接ORACLE的几种方法

一、HOSTNAME方法对于网络结构比较单一&#xff0c;Oracle服务器比较少的情况下&#xff0c;可以使用HOSTNAME方法。不过这种方法有几个限制&#xff1a;1、 必须使用TCP/IP协议2、 不能使用高级管理工具&#xff0c;比如Oracle Connection Manager3、 客户端必须有相应的扩展命…

swiper.js pagination指示点不变_电缆故障点的四种实用测定方法

一、电缆故障的种类与判断无论是高压电缆或低压电缆&#xff0c;在施工安装、运行过程中经常因短路、过负荷运行、绝缘老化或外力作用等原因造成故障。电缆故障可概括为接地、短路、断线三类&#xff0c;其故障类型主要有以下几方面&#xff1a;①三芯电缆一芯或两芯接地。②二…