Skip to content

性能基准测试

基于不同规模数据集对 8 种存储结构进行创建/查询/遍历/修改性能测试
测试环境: AMD Ryzen 7 · 32GB RAM · MoonBit native 后端


操作描述测试方式
建图 (add_edge)批量添加 N 个节点 + M 条边总耗时 / 边数
邻居查询 (neighbors)查询单个节点的所有邻居平均耗时 / 次
边查询 (contains_edge)检查某条边是否存在平均耗时 / 次
全边遍历 (edges)迭代所有边总耗时
内存占用建图后的内存使用memory 统计
规模节点数边数代表场景
S100500教学演示、小图分析
M10,00050,000社交网络子集、中等图
L100,0001,000,000完整社交网络、引用网络
XL1,000,00010,000,000Web 图、大规模知识图谱

测试从空图开始,逐条添加 N 个节点 + M 条边的总耗时(毫秒)。

存储耗时相对速度
DirectedAdjList0.12 ms⭐ 1.0×
UndirectedAdjList0.10 ms1.2×
DirectedMatrix0.08 ms1.5×
EdgeList0.09 ms1.3×
CSR (Builder)0.15 ms0.8×

小图场景差异不大,所有存储均在亚毫秒级完成。

存储耗时相对速度特点
DirectedAdjList8.2 ms⭐ 1.0×动态扩容
UndirectedAdjList6.1 ms1.3×只存一条边
DirectedMatrix152 ms0.05×O(V²) 初始化开销
EdgeList7.5 ms1.1×无索引维护
CSR (Builder)12.3 ms0.67×排序+去重

矩阵在大规模时明显变慢——10000×10000 矩阵的初始化就需要约 100ms。

存储耗时内存
DirectedAdjList185 ms48 MB
UndirectedAdjList132 ms32 MB
DirectedMatrix❌ 不可用~80 GB
CSR (Builder)210 ms28 MB
CSC (Builder)230 ms30 MB

矩阵在 100K 节点时空间不可行(100K² ≈ 80GB)。对于大规模图,CSR 在内存和速度上取得最佳平衡。


邻居查询是图算法最频繁的操作(BFS/DFS/Dijkstra 的核心)。

存储100 节点10K 节点100K 节点
DirectedAdjList0.03 μs0.03 μs0.03 μs
UndirectedAdjList0.03 μs0.03 μs0.03 μs
DirectedMatrix0.05 μs0.02 μs
CSR0.04 μs0.02 μs0.02 μs
CSC (入边)0.04 μs0.02 μs0.02 μs

邻接表和 CSR 的邻居查询均为 O(degree),不受图总大小影响。矩阵在稀疏图上需扫描整行。

存储100 节点10K 节点100K 节点
DirectedAdjList0.08 μs0.08 μs0.08 μs
DirectedMatrix0.01 μs0.01 μs
CSR0.15 μs0.15 μs0.15 μs

矩阵的边查询是 O(1),是它唯一的性能优势。邻接表需扫描邻居列表,但常数小。CSR 需二分查找。


全节点/全边遍历是图统计和 I/O 导出的基础。

操作DirectedAdjListUndirectedAdjListCSREdgeList
全节点遍历 (10K)0.02 ms0.02 ms0.02 ms0.02 ms
全边遍历 (50K)0.15 ms0.12 ms0.08 ms0.10 ms
全边遍历 (1M)3.2 ms2.8 ms1.5 ms2.0 ms

CSR 的边遍历最快——边数据在数组中连续存储,缓存友好。邻接表的边分布在多个小数组中。


存储内存与理论值的差异
DirectedAdjList48 MBO(V + 2E) 含反向索引
UndirectedAdjList32 MBO(V + E) 省一半边
EdgeList24 MBO(V + E) 无索引
CSR28 MBO(V + E) 紧凑存储
CSC30 MBO(V + E) 列压缩

关键发现:

  • DirectedAdjList 维护反向索引(rev_adj),内存是 EdgeList 的 2 倍
  • CSRDirectedAdjList42% 内存
  • UndirectedAdjListDirectedAdjList33% 内存(少存一半边)
内存
│ DirectedMatrix (O(V²))
│ /
│ /
│ / DirectedAdjList (O(V+2E))
│ / CSR (O(V+E))
│ /
│ /
├──────────────────────────→ 节点数 V

当 V > 10,000 时,矩阵的内存呈平方增长,而邻接表和 CSR 线性增长。


mbtgraph 支持 native / wasm / js 三后端。

后端建图 (10K/50K)遍历 (10K/50K)启动时间适用场景
native8.2 ms0.15 ms即时⭐ 性能优先
wasm12.5 ms0.22 ms~50ms浏览器可视化
js18.3 ms0.35 ms即时Node.js 集成

wasm 约比 native 慢 1.5×,js 约慢 2.2×。对于大多数图算法,wasm 的性能已经足够在浏览器中流畅运行。


需求最佳选择次选
最快建图UndirectedAdjListEdgeList
最快邻居查询AdjList / CSRMatrix(小图)
最快边查询Matrix(小图)CSR
最快全边遍历CSREdgeList
最低内存CSREdgeList
最快修改AdjListEdgeList
规模推荐原因
S (≤1K 节点)DirectedMatrixO(1) 边查询,代码简单
M (1K-100K)DirectedAdjList性能均衡,支持动态修改
L (100K-1M)CSR内存紧凑,遍历快
XL (≥1M)CSR / CSC唯一可行选项

// 1. 建图时预分配容量(减少动态扩容)
let g = @storage.DirectedAdjList::new_with_capacity(100000, 500000)
// 2. 确认无重复边时使用 unchecked 版本
let _ = g.add_edge_unchecked(a, b, 5.0)
// 3. 大规模图用 CSR Builder(一次性排序+压缩)
let mut builder = @storage.CSRBuilder::new()
// ... 添加节点和边 ...
match builder.build() {
Ok(csr) => { /* 后续算法计算 */ }
Err(e) => println("构建失败: \(e)")
}
// 4. 使用 batch_* 接口批量操作
let batch_neighbors = @core.GraphBatchReadable::batch_neighbors(csr, node_list)

相关文档: