原文链接: fiber 遍历方式比较
上一篇: react fiber 遍历方式简单实现
下一篇: 使用生成器模拟时间分片
对比递归和fiber链表式遍历方式的速度
fiber综合上能快一倍
function splitInt(n, count) {
if (n < 2) return [n]
let list = [...Array(count - 1)]
.map(i => parseInt(Math.random() * n))
.sort((a, b) => a - b)
list.push(n)
list.unshift(0)
// console.log(list.filter(i => i < 0))
let res = []
for (let i = 1; i <= count; i++) {
res.push(list[i] - list[i - 1])
}
return res
}
class Node {
constructor(id, child = []) {
this.id = id
this.child = child
}
}
function getTree(count, maxChild = 16) {
let id = 0
// 创建n个节点的树
function buildTree(n) {
if (n === 1) return new Node(id++)
let childCount = splitInt(n - 1, maxChild)
let root = new Node(id++)
// console.log('n', n, childCount)
for (let i of childCount) {
if (i < 1) continue
root.child.push(buildTree(i))
}
return root
}
return buildTree(count)
}
class FNode {
constructor(id, sibling, parent, child = []) {
this.id = id
this.parent = parent
this.child = child
this.sibling = sibling
}
}
function getNodeNum(root) {
let count = 0
function dfs(r) {
if (!r) return
count++
for (let i of r.child)
dfs(i)
}
dfs(root)
return count
}
function tree2fiber(tree) {
let root = new FNode(tree.id)
let nodes = tree.child
let preNode = null
for (let i = 0; i < nodes.length; i++) {
let node = tree2fiber(nodes[i])
node.parent = root
if (i === nodes.length - 1) {
node.sibling = null
// preNode.sibling = node
}
preNode && (preNode.sibling = node)
preNode = node
root.child.push(node)
}
return root
}
// 返回字符串
function recursion(root) {
let res = []
function dfs(r) {
if (!r) return
res.push(r.id)
for (let i of r.child)
dfs(i)
}
dfs(root)
return res
}
// 返回字符串
function fiber(root) {
let res = []
let current = root
while (true) {
res.push(current.id)
if (current.child.length) {
current = current.child[0]
continue
}
if (current === root) {
break
}
while (!current.sibling) {
// 如果我们回到了根节点,退出函数
if (!current.parent || current.parent === root) {
return res;
}
// 设置父节点为当前活跃节点
current = current.parent;
}
current = current.sibling
}
return res
}
let time1 = []
let time2 = []
let countList = []
for (let pow = 1; pow < 100; pow++) {
let testCount = 100
let COUNT = 1000 * pow
countList.push(COUNT)
let sum1 = 0
let sum2 = 0
for (let i = 0; i < testCount; i++) {
let root = getTree(COUNT, 16)
// console.log(getNodeNum(root))
// let root = getBinTree(COUNT)
let fiberLink = tree2fiber(root)
let st2 = +new Date()
let dfsRes = recursion(root)
let ed2 = +new Date()
let st1 = +new Date()
let fiberRes = fiber(fiberLink)
let ed1 = +new Date()
// console.log('fiber', ed1 - st1, 'dfs', ed2 - st2, fiberRes.join('') === dfsRes.join(''))
// console.log(getNodeNum(root), fiberRes.length)
// console.log(dfsRes.join(','))
// time1.push(ed1 - st1)
// time2.push(ed2 - st2)
sum1 += (ed1 - st1)
sum2 += (ed2 - st2)
}
time1.push(sum1 / testCount)
time2.push(sum2 / testCount)
}
console.log(time1.join(','))
console.log(time2.join(','))
console.log(countList.join(','))
// 二叉树
// 0.09,0.1,0.18,0.14,0.22,0.46,0.43,0.44,0.45,0.51,0.71,0.69,0.96,0.74,0.94,1.09,1.12,1.21,1.32,1.35,1.33,1.53,1.92,1.69,1.98,2.09,2.01,2.11,2.11,2.22,2.27,2.23,2.44,2.62,2.62,3.13,2.72,2.9,2.66,2.68,2.87,2.74,2.71,3.05,2.99,2.97,3.09,3.21,3.19,3.33,3.83,3.87,3.88,3.96,4.16,4.25,4.36,4.12,4.41,4.3,4.49,4.42,4.65,4.68,4.9,4.9,4.76,4.96,4.93,4.91,5.4,5.2,5.04,5.16,5.36,5.58,5.95,5.97,6.09,5.99,6.05,5.99,6.06,6.24,6.43,6.37,6.31,6.31,6.35,6.44,6.58,6.6,6.81,6.76,6.8,6.94,6.95,6.85,7
// 0.07,0.15,0.2,0.3,0.24,0.36,0.44,0.33,0.56,0.62,0.41,0.95,0.87,1.19,1.2,1.55,1.37,1.56,1.48,2,2.21,1.89,2.52,2.69,3.26,2.85,3.44,3.98,3.78,3.72,4,4.15,4.37,4.84,5.02,5.45,5.96,6.28,7.2,7.19,7.66,7.66,7.59,8.61,8.28,8.32,8.42,7.84,7.7,7.66,8.81,8.01,8.19,7.72,7.91,7.86,7.48,7.41,8.23,7.99,8.18,8.7,9.15,9.26,7.28,8.85,8.69,8.53,8.95,9.1,9.35,9.83,9.88,10.03,10.07,10.22,11.1,10.94,11.48,11.51,11.77,11.7,11.55,11.83,11.8,12.32,12.12,12.4,11.25,10.83,12.45,12.09,13.48,12.51,12.13,12.3,13.63,12.78,12.13
// 随机树
// 0.03,0.08,0.06,0.09,0.16,0.11,0.12,0.29,0.2,0.22,0.33,0.35,0.39,0.43,0.35,0.74,0.68,0.67,0.61,0.77,0.72,0.69,0.88,1.06,1.09,1.03,1.17,1.03,1.24,1.03,1.04,1.11,1.58,1.55,1.53,1.64,1.61,1.63,1.58,1.59,1.78,1.73,1.72,1.98,1.76,1.74,1.65,1.86,1.86,2,2.36,2.31,2.41,2.36,2.36,2.55,2.34,2.92,2.69,2.71,2.58,2.76,2.97,2.85,2.54,2.97,3.15,3,3,3.02,2.99,3.07,2.99,3.24,3.02,3.26,3.76,3.97,3.54,3.77,5.12,3.98,4.05,4.14,4.2,4.05,4.14,5.12,4.39,4.32,4.33,4.45,4.32,4.8,5.84,5.34,4.72,4.47,4.83
// 0.06,0.11,0.16,0.24,0.28,0.26,0.34,0.31,0.47,0.43,0.65,0.63,0.81,0.65,0.69,0.99,0.96,1.07,0.9,1.02,1.24,1.32,1.42,1.47,1.56,1.61,1.69,1.7,1.59,1.92,1.89,1.99,2.02,2.36,2.42,2.88,2.43,2.38,2.62,2.63,2.54,2.52,2.59,2.95,2.83,2.91,2.95,2.76,2.94,2.97,3.53,3.55,4.03,3.48,3.58,3.41,3.53,3.71,3.88,3.59,3.68,3.91,3.91,3.83,4.14,4.14,4.08,4.3,4.24,4.41,4.17,4.24,4.72,4.73,4.45,4.39,5.36,5.07,6.06,5.08,6.49,5.33,5.3,5.28,5.41,5.81,5.67,5.71,5.67,5.78,5.52,5.61,5.68,6.01,6.09,6.2,6.7,6.84,7.14
// 1000,2000,3000,4000,5000,6000,7000,8000,9000,10000,11000,12000,13000,14000,15000,16000,17000,18000,19000,20000,21000,22000,23000,24000,25000,26000,27000,28000,29000,30000,31000,32000,33000,34000,35000,36000,37000,38000,39000,40000,41000,42000,43000,44000,45000,46000,47000,48000,49000,50000,51000,52000,53000,54000,55000,56000,57000,58000,59000,60000,61000,62000,63000,64000,65000,66000,67000,68000,69000,70000,71000,72000,73000,74000,75000,76000,77000,78000,79000,80000,81000,82000,83000,84000,85000,86000,87000,88000,89000,90000,91000,92000,93000,94000,95000,96000,97000,98000,99000