node和go的列表转树形, 执行速度测试对比

保证数据一致性,先生成4000条json数据到本地,然后分别读取文本执行处理

node代码

node是用midway框架

forNum1:number = 0forNum2:number = 0//执行测试async index(){// 生成菜单列表// const menuList = await this.generateMenuList([], 4000);const menuListStr = 	fs.readFileSync(this.app.getAppDir()+'/public/listJson.txt', 'utf8');const menuList = JSON.parse(menuListStr)console.time("4000条 引用类型 时间:deepTree");await this.deepTree(menuList);console.log("4000条 引用类型 时间:")console.timeEnd("4000条 引用类型 时间:deepTree");console.log("循环次数",this.forNum1)// this.logger.info("deepTree 数据", JSON.stringify(l));console.time("4000条 递归 时间:deepTree2");await this.deepTree2(menuList, null);console.timeEnd("4000条 递归 时间:deepTree2");console.log("循环次数",this.forNum2)}// 列表转树形async deepTree(list: any[]){const newList: any[] = [];const map: any = {};for (let index = 0; index < list.length; index++) {this.forNum1++const e = list[index];map[e.id] = e;}for (let index = 0; index < list.length; index++) {this.forNum1++const e = list[index];const parent = map[e.parentId];if (parent) {(parent.children || (parent.children = [])).push(e);} else {newList.push(e);}}return newList;}// 递归遍历async deepTree2(arr: any[], parentId: any) {// const loop = (parentId: any) => {//   return arr.reduce((pre, cur) => {//     this.forNum2++//     if (cur.parentId == parentId) {//       cur.children = loop(cur.id);//       pre.push(cur);//     }//     return pre;//   }, []);// }const list = []const loop = (parentId: any)=>{for (let index = 0; index < arr.length; index++) {this.forNum2++if (arr[index].parentId == parentId) {arr[index].children = loop(arr[index].id);list.push(arr[index]);}}return list}return loop(parentId);}//生成随机的菜单列表数据,给转换树形菜单使用async generateMenuList(menuList: { id: number; parentId: number | null }[] = [],maxDepth: number = 5){// 如果菜单列表长度达到1000,则停止生成if (menuList.length > maxDepth || menuList.length >= 10000) {return menuList;}const nextID = menuList.length + 1// 如果菜单列表不为空,则随机选择一个已存在的id作为parentId;否则parentId为nulllet parentId: number | null = null;if (menuList.length > 0) {parentId = menuList[Math.floor(Math.random() * menuList.length)].id;}// 将新菜单项添加到列表中menuList.push({ id:nextID, parentId });// 递归调用生成子菜单项,深度加1return this.generateMenuList( menuList, maxDepth);}

测试结果
在这里插入图片描述

go代码

go框架是goframe

var (ctx     context.ContextforNum1 = 0forNum2 = 0
)type MenuItem struct {ID       *int        `json:"id"`       // 节点的唯一标识符ParentId *int        `json:"parentId"` // 父节点的IDChildren []*MenuItem `json:"children"` // 子节点列表
}
// 遍历树
func DeepTree(strSlice []*MenuItem) interface{} {var (strMap  = make(map[int]*MenuItem)newList []*MenuItem)for i := range strSlice {node := strSlice[i]strMap[*node.ID] = nodeforNum1++}for i := range strSlice {node := strSlice[i]if *node.ParentId != 0 {strMap[*node.ParentId].Children = append(strMap[*node.ParentId].Children, node)} else {newList = append(newList, node)}forNum1++}return newList
}// 执行递归
func DeepTree2(strSlice []*MenuItem, parentId int) interface{} {var (loop func([]*MenuItem, int) []*MenuItemlist []*MenuItem)loop = func(strSlice []*MenuItem, parentId int) []*MenuItem {for i := range strSlice {forNum2++if parentId == 0 {if *(strSlice[i].ParentId) == 0 {strSlice[i].Children = loop(strSlice, *(strSlice[i].ID))list = append(list, strSlice[i])}} else if *(strSlice[i].ParentId) != 0 && *(strSlice[i].ParentId) == parentId {strSlice[i].Children = loop(strSlice, *(strSlice[i].ID))list = append(list, strSlice[i])}}return list}return loop(strSlice, parentId)
}// 生成随机菜单列表数据
func generateMenuList(menuList []*MenuItem, maxDepth int) []*MenuItem {// 如果菜单列表长度达到10000,则停止生成if len(menuList) >= maxDepth || len(menuList) >= 10000 {return menuList}nextID := len(menuList) + 1// 如果菜单列表不为空,则随机选择一个已存在的id作为parentId;否则parentId为nilvar parentId intif len(menuList) > 0 {existingItem := menuList[rand.Intn(len(menuList))]parentId = *(existingItem.ID)}// 将新菜单项添加到列表中menuList = append(menuList, &MenuItem{ID: &nextID, ParentId: &parentId})// 递归调用生成子菜单项,深度加1return generateMenuList(menuList, maxDepth)
}

开始测试

func Test(t *testing.T) {var (menuSlice []*MenuItem)//menuSlice = generateMenuList([]*MenuItem{}, 15)//gfile.PutContents("./listJson-15.txt", gconv.String(menuSlice))jsonStr := gfile.GetContents("./listJson-4000.txt")err := gconv.Scan(jsonStr, &menuSlice)if err != nil {return}startTime1 := time.Now()DeepTree(menuSlice)endTime1 := time.Now()logInfo1 := fmt.Sprintf("\n %d条 引用类型 时间:%v,循环次数:%d\n--------", len(menuSlice), endTime1.Sub(startTime1), forNum1)g.Log().Debug(ctx, logInfo1)startTime2 := time.Now()DeepTree2(menuSlice)endTime2 := time.Now()logInfo2 := fmt.Sprintf("\n %d条 引用类型 时间:%v,循环次数:%d\n--------", len(menuSlice), endTime2.Sub(startTime2), forNum2)g.Log().Debug(ctx, logInfo2)}

测试结果:
在这里插入图片描述

测试连续10次的数据
在这里插入图片描述

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

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

相关文章

2024年腾讯云免费服务器最新申请入口链接

腾讯云免费服务器申请入口 txybk.com/go/free 免费服务器可选轻量应用服务器和云服务器CVM&#xff0c;轻量配置可选2核2G3M、2核8G7M和4核8G12M&#xff0c;CVM云服务器可选2核2G3M和2核4G3M配置&#xff0c;腾讯云百科txybk.com分享2024年最新腾讯云免费服务器申请入口、限制…

【数值计算方法】4 / 数值积分

一、理解插值 二、几种理解方式&#xff1a; 1、对插值函数进行积分得到&#xff1b; 2、使用另一个函数近似&#xff1b;&#xff08;三角函数、指数函数都是可以的...) 3、使用拉格朗日插值&#xff1b;----代数精度法&#xff08;权和为1&#xff09; 三、

深度神经网络(DNN)

通过5个条件判定一件事情是否会发生&#xff0c;5个条件对这件事情是否发生的影响力不同&#xff0c;计算每个条件对这件事情发生的影响力多大&#xff0c;写一个深度神经网络&#xff08;DNN&#xff09;模型程序,最后打印5个条件分别的影响力。 示例 在深度神经网络&#xf…

【深度学习】Dropout、DropPath

一、Dropout 1. 概念 Dropout 在训练阶段会让当前层每个神经元以drop_prob&#xff08; 0 ≤ drop_prob ≤ 1 0\leq\text{drop\_prob}\leq1 0≤drop_prob≤1&#xff09;的概率失活并停止工作&#xff0c;效果如下图。 在测试阶段不会进行Dropout。由于不同批次、不同样本的神…

open Gauss 数据库-06 openGauss数据库安全指导手册5.0.0

发文章是为了证明自己真的掌握了一个知识&#xff0c;同时给他人带来帮助&#xff0c;如有问题&#xff0c;欢迎指正&#xff0c;祝大家万事胜意&#xff01; 目录 前言 openGauss数据库安全指导 1 用户权限控制 1.1 实验介绍 1.1.1 关于本实验 1.1.2 实验目的 1.2 用户…

初识ansible变量及实例配置

目录 1、为什么要使用变量 2、变量分类 3、 变量详解 3.1 vars,vars_files , group_vars 3.1 .1 vars 剧本中定义变量 3.1.2 vars_file 将变量存放到一个文件中&#xff0c;并在剧本中引用 3.1.3 group_vars 创建一个变量文件给某个组使用 实例1-根据不同的主机…

如何在PostgreSQL中使用pg_stat_statements插件进行SQL性能统计和分析?

文章目录 一、启用pg_stat_statements插件二、查看统计信息三、定期重置统计信息四、注意事项 PostgreSQL中的pg_stat_statements是一个强大的插件&#xff0c;用于追踪执行时间最长的SQL语句。通过它&#xff0c;我们可以获取有关SQL语句执行频率、总执行时间、平均执行时间等…

四.RocketMQ的几种消息发送方式应用

RocketMQ的几种消息发送方式应用 一&#xff1a;普通消息1&#xff09;发送同步消息2&#xff09;发送异步消息3&#xff09;单向发送消息4&#xff09;消费消息-负载均衡模式5&#xff09;消费消息-广播模式 二&#xff1a;顺序消息1.顺序消息指的是:严格按照消息的发送顺序进…

【免费源码下载】完美运营版商城 虚拟商品全功能商城 全能商城小程序 智慧商城系统 全品类百货商城php+uniapp

简介 完美运营版商城/拼团/团购/秒杀/积分/砍价/实物商品/虚拟商品等全功能商城 干干净净 没有一丝多余收据 还没过手其他站 还没乱七八走的广告和后门 后台可以自由拖曳修改前端UI页面 还支持虚拟商品自动发货等功能 挺不错的一套源码 前端UNIAPP 后端PHP 一键部署版本&am…

【Linux】在centos快速搭建K8S1.18集群

使用 kubeadm 创建集群帮助文档 如果您需要以下几点&#xff0c;该工具是很好的选择&#xff1a;kubeadm 一种简单的方法&#xff0c;让你尝试 Kubernetes&#xff0c;可能是第一次。现有用户自动设置群集并测试其应用程序的一种方式。其他生态系统和/或安装程序工具中的构建…

k8s安装,linux-ubuntu上面kubernetes详细安装过程

官方文档&#xff1a;https://kubernetes.io/zh-cn/docs/setup/production-environment/container-runtimes/ 环境配置 该部分每个主机都要执行 如果你确定不需要某个特定设置&#xff0c;则可以跳过它。 设置root登录 sudo passwd root sudo vim /etc/ssh/sshd_config Perm…

Linux华硕笔记本安装ROG Asusctl

基础环境 适用系统&#xff1a; linux mint 21ubuntu 22.04 安装版本&#xff1a; asusctl-5.0.10rust 1.77.2 构建 安装编译环境 sudo apt-get update sudo apt-get install -y \libasound2-dev \libfreetype6-dev \libexpat1-dev \libxcb-composite0-dev \libssl-dev …