perf(pagerank): O(V+E) 累加实现替代 O(V²) 全源遍历
旧实现每目标节点遍历全部源节点找边匹配 (943-961): - 17628 nodes × 20 迭代 = 6.2亿次内层操作 → 单次 PageRank ~3 分钟 - 重启后多套触发器零值连锁 fire full consolidation → CPU 100% 持续 10+ 分钟 新实现先归一化每源节点总权重, 再沿出边把贡献累加到目标 (O(V+E)): - 17628 nodes PageRank + 图谱维护: 3分钟 → <1 秒 - 重启风暴从 10+ 分钟 CPU 100% → 秒级无感 实测: 01:16:40 图谱维护开始 → 01:16:41 PageRank 更新 17628 nodes 完成
This commit is contained in:
parent
e67f0bc7a6
commit
6c1c21fadf
|
|
@ -941,21 +941,26 @@ func (gs *SQLiteGraphStore) PageRank(damping float64, iterations int) map[string
|
|||
}
|
||||
|
||||
for iter := 0; iter < iterations; iter++ {
|
||||
newRanks := make(map[string]float64)
|
||||
for _, node := range nodes {
|
||||
rank := base
|
||||
for src, edges := range outEdges {
|
||||
totalWt := 0.0
|
||||
for _, e := range edges {
|
||||
totalWt += e.weight
|
||||
}
|
||||
for _, e := range edges {
|
||||
if e.target == node && totalWt > 0 {
|
||||
rank += damping * ranks[src] * e.weight / totalWt
|
||||
}
|
||||
}
|
||||
// 正确 PageRank 实现 O(V+E):先归一化每个源节点总权重,
|
||||
// 再沿出边把贡献直接累加到目标节点(旧实现每目标遍历全源 O(V²),
|
||||
// 17628 节点 × 20 迭代 = 6.2 亿次 → 3 分钟;现在亚秒级)
|
||||
contrib := make(map[string]float64, len(outEdges))
|
||||
for src, edges := range outEdges {
|
||||
totalWt := 0.0
|
||||
for _, e := range edges {
|
||||
totalWt += e.weight
|
||||
}
|
||||
newRanks[node] = rank
|
||||
if totalWt <= 0 {
|
||||
continue
|
||||
}
|
||||
share := damping * ranks[src] / totalWt
|
||||
for _, e := range edges {
|
||||
contrib[e.target] += share * e.weight
|
||||
}
|
||||
}
|
||||
newRanks := make(map[string]float64, len(nodes))
|
||||
for _, node := range nodes {
|
||||
newRanks[node] = base + contrib[node]
|
||||
}
|
||||
ranks = newRanks
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue