前言

今天让我们来继续聊一聊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次稳定后的结果如图:

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

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

  1. js分页列表找出最后一页的最后一条数据

    需求场景: 需求描述:如图所示,想要实现列表中排第一位向上的箭头隐藏, 列表中排最后一位向下的箭头隐藏 问题描述: 因为列表存在分页,数据不确定,所以不确定最后一位是否在第几页 代码实现: html: ...

  2. js中forEach以及forEach跳出循环

    for与forEach的区别 1.for循环可以使用break跳出循环,但forEach不能.那forEach能不能跳出循环呢?可以,不过不是使用break,而是结合try catch操作(下面有写如 ...

  3. 原生js使用forEach()与jquery使用each遍历数组,return false 的区别

    原生js使用forEach()与jquery使用each()遍历数组,return false 的区别: 1.使用each()遍历数组a,如下: var a=[20,21,22,23,24];$.ea ...

  4. js中foreach有三种写法,你知道吗

    JavaScript的foreach 初始化 写法 1.经典写法 2.js的foreach 3.es6的foreach 初始化 先创建一个h5文件,并定义一个数组 <!DOCTYPE html& ...

  5. Js中forEach,for in,for of循环的用法

    取出数组里边对象的key和value值: 取出数组里边对象的key和value值_chu_geng的博客-CSDN博客_获取数组里面对象的value值 转自:js中forEach,for in,for ...

  6. js for forEach 跳出循环方式

    js for forEach 跳出循环方式 文章目录 js for forEach 跳出循环方式 前言 一.for循环 二.for in 循环 三.forEach循环 问题 解决办法 前言 JS中的循 ...

  7. php foreach 为什么在if条件下多条数据只取出一条数据_微信大牛教你深入了解数据库索引...

    ​| 作者 刘国斌,腾讯微信事业群研发工程师,目前从事企业微信的后台研发工作,已经参与企业微信消息系统.群聊.客户联系等企业微信多个核心功能的迭代. 数据库查询是数据库的最主要功能之一.我们都希望查询 ...

  8. js:nodejs搭建http服务器为页面添加mysql中的数据分页

    一,建立两个模板:db.js (获取数据库的数据)  message.js(将得到的数据进行分页,显示) db.js /*** 创建数据库连接,并获取数据*/ var mysql = require( ...

  9. python flask + js ajax + echarts 53万条招聘信息可视化系统的渣实现

    (从0到1非常详细步骤)flask+ajax+echarts 53万条招聘信息可视化系统的实现   本篇blog默认:您已经入门echarts.html.js.json.python,知道一些大概的东 ...

最新文章

  1. 169v 条目不存在_存在麒麟?牛顿烈焰激光剑理论!生活中的科学思维
  2. secureCRT自动断开的解决方法
  3. markdown转html
  4. Python之pandas:pandas的get_dummies函数简介(将分类变量转为哑变量)及其使用方法之详细攻略
  5. hibernate mysql 映射_hibernate与mysql映射类型对应表与mysql导入导出
  6. 【已解决】Exception in thread “Thread-0“ redis.clients.jedis.exceptions.JedisConnectionException: java.n
  7. 使用jquery当页面打开时,将修改样式的点击事件绑定到Dom
  8. 1.3编程基础之算术表达式与顺序执行 20 计算2的幂
  9. nginx开启支持websocket连接
  10. Qt error: collect2: error: ld returned 1 exit status
  11. 重构第0天--重构的理解
  12. 办公协同:xmind8案例实战班-Array老师-专题视频课程
  13. QT教程—1.1Qt入门
  14. 不能是underfined.xxx
  15. 【Latex】用Acrobat剪切pdf文件中图
  16. 非本小伙花了两年从小公司到蚂蚁金服,面试经验分享
  17. python 游戏大作_使用requests和beautifulsoup爬取3DM单机大作排行榜
  18. String 判断纯数字 正则式
  19. RPG冒险类游戏:矮人The Dwarves for Mac中文版(支持m1)
  20. IBM bladecenter H刀箱BladeCenter北电交换机VLAN配置

热门文章

  1. 制作安装媒体来部署额外域控制器
  2. 《统一沟通-微软-实战》-6-部署-2-中介服务器-5-语音路由-语音策略
  3. EntitySpaces2009的开发文档地址
  4. Redo Log 和Checkpoint not complete
  5. select * 排除字段_编写 SQL 的排除联接
  6. Hive的使用之hwi
  7. oracle中的(+)
  8. csgo客户文件与服务器,csgo与远程服务器
  9. 微软封闭服务器切换,执行服务器切换:Exchange 2013 帮助 | Microsoft Docs
  10. [转载] 整理下java中stringBuilder和stringBuffer两个类的区别