petgraph vs rustworkx / rustworkx-core:Rust 與 Python 圖計算怎麼選
petgraph vs rustworkx / rustworkx-core:Rust 與 Python 圖計算怎麼選
如果你在做 GraphRAG、推薦系統、關係網分析,常見的分歧是:
「我要一個純 Rust 的圖資料結構庫(方便客製)」,還是「我要一個現成的高效圖演算法工具箱(省時間)」?而當你同時要支援 Python 生態(例如要像 NetworkX 一樣用),選項又會再分叉一次。
本文把三個東西拆開講清楚:
- petgraph:純 Rust 圖資料結構 + 基礎演算法的通用底座
- rustworkx(Python 套件):Rust 實作、PyO3 綁定的高效 Python 圖庫(API 風格接近 NetworkX)
- rustworkx-core(Rust crate):把 rustworkx 的部分演算法抽成「可被下游 Rust 專案重用」的泛型演算法 crate(建立在 petgraph 之上)
TL;DR:怎麼選
- 你是純 Rust 專案,核心需求是「圖結構 + 自訂演算法/資料」:選 petgraph
- 你是 Rust 專案,但想直接拿到更多「現成、成熟」的演算法模組(中心性、連通性、節點合併/收縮等):在 petgraph 基礎上加 rustworkx-core
- 你是 Python 專案,NetworkX 太慢,想要相似心智模型但要更快:選 rustworkx(Python)
三者的關係:誰建立在誰上面
- petgraph 是 Rust 世界常用的圖資料結構庫:提供多種 graph type(例如
Graph、StableGraph、GraphMap、MatrixGraph、Csr),以及基本演算法(例如 Dijkstra、BFS)與 DOT 輸出等能力。 - rustworkx(Python)是「用 Rust 寫高效圖運算,再用 PyO3 給 Python 用」的路線,且 API 設計刻意接近 NetworkX,方便替換。
- rustworkx-core(Rust)是把 rustworkx 的一部分演算法抽離,做成 對 petgraph graph trait 友善的泛型函式,讓 Rust 下游專案不用依賴 Python 層也能享受同一批演算法。
功能比較(以工程選型角度)
| 面向 | petgraph | rustworkx-core(Rust) | rustworkx(Python) |
|---|---|---|---|
| 主要定位 | 資料結構 + 基礎演算法 | petgraph 之上的「演算法擴充」 | Python 圖庫(Rust 實作) |
| 語言 / API | 純 Rust | 純 Rust(泛型 API) | Python API(PyO3 綁定) |
| 圖型別 | 多種 graph type,取捨清晰 | 通常直接吃 petgraph 的 graph | PyGraph / PyDiGraph 等 Python 封裝 |
| 演算法覆蓋 | 基本款 + 一些常用演算法 | 更偏圖分析/圖運算工具箱 | 最完整、最貼近使用者(含大量 Python 封裝) |
| 多執行緒 | 取決於你怎麼寫/用 | 部分演算法設計可並行(依實作而定) | 多個演算法有 rayon 並行與 threshold 設計 |
| 安裝/整合 | Rust 專案直接用 | Rust 專案直接用(cargo) | Python wheel / sdist(並提供 Stable ABI 相容路線) |
什麼算「擴展」:rustworkx 0.17.x 的演算法面向
以 rustworkx 0.17.x 的釋出重點來看,它在「圖分析與工程化能力」上補了不少常用拼圖,例如:
- 更完整的連通性/強連通性能力:強連通檢查、SCC 數量等
- condensation(縮點/商圖):把 SCC 或 connected components 壓縮成新圖並給 node map
- 中心性/統計類演算法:例如加權 closeness(Newman 方法)、closeness 的平行化
- 路徑相關 API 強化:例如
all_simple_paths支援多 target - 圖輸出/交換:例如 GraphML 寫出支援
- 新的 Rust core 函式:0.17.1 新增
rustworkx_core::shortest_path::distance_matrix,讓 Rust 專案能直接用到距離矩陣功能(對應 Python 的distance_matrix())
對「GraphRAG 查詢端」來說,這些能力常常正好落在:
「我要做社群/中心性做 node ranking」、「我要把強連通縮點當成 query-time 的加速結構」、「我要批次路徑特徵」這類需求。
效能:該怎麼正確看 benchmark
你可以把效能問題拆成兩層:
- 語言與資料結構層:從 Python(NetworkX)換到 Rust(petgraph/rustworkx)本身就會是大幅躍升
- 演算法與平行化層:同樣在 Rust,是否有用到成熟、可並行的實作,會再拉開差距
rustworkx 官方 benchmark 的結論方向是:它在多個工作負載上對比 Python 生態常用圖庫表現很強,並且相對 NetworkX 可以有數倍到數十倍的差距(實際倍率會依圖大小、稀疏度、演算法而大幅變動)。在工程上建議的做法是:
- 先用你自己的真實圖資料集(或抽樣)跑一次基準
- 再決定是只換資料結構(petgraph)還是直接換成演算法更完整的工具箱(rustworkx-core / rustworkx)
Rust 專案:如何把 petgraph 升級成「petgraph + rustworkx-core」
這個遷移通常是「加法」而不是「替換」:你仍然用 petgraph 的圖型別與資料結構,只是把部分演算法呼叫改成 rustworkx-core 的實作。
Cargo.toml
[dependencies]
petgraph = "0.8"
rustworkx-core = "0.17"
實務上要注意的是:petgraph 版本要跟 rustworkx-core 相容。如果你碰到 trait bound 或型別不匹配,第一個要檢查的就是兩者版本是否在同一個相容區間。
直接用 rustworkx-core re-export 的 petgraph(可選)
rustworkx-core 會 re-export petgraph,所以你也可以把 import 統一從 rustworkx-core 出口進來,避免依賴樹中出現多份 petgraph:
use rustworkx_core::petgraph;
use rustworkx_core::centrality::betweenness_centrality;
let g = petgraph::graph::UnGraph::<i32, ()>::from_edges(&[
(1, 2), (2, 3), (3, 4), (1, 4)
]);
let output = betweenness_centrality(&g, false, false, 200);
Graph extension:把「節點合併/收縮」變成方法
rustworkx-core 也提供一些 extension trait,讓你對特定 petgraph graph type 直接呼叫額外方法(例如 node contraction 相關能力)。在工程上好處是:你可以把「建圖」與「加速結構變換」留在 Rust 端完成,讓 Python 端只做輕量呼叫或結果消費。
Python 專案:什麼時候該直接用 rustworkx
如果你的目標是「NetworkX-style 開發體驗」,又希望演算法直接給你拿來用,那 rustworkx(Python 套件)通常是最短路徑。
幾個實務上的判斷點:
- 你不想維護自己的 PyO3 binding:rustworkx 已經把大量 API 與效能細節封裝好
- 你需要輪子完整:例如 shortest paths、中心性、子圖同構、圖生成等常用工具
- 你要跨多個 Python 版本部署:rustworkx 0.17.x 走 Python Stable ABI,相容範圍覆蓋 Python 3.9+,對部署與發 wheel 友好
Rust + PyO3:兩種整合策略(給 GraphRAG 類專案)
你在 Rust 寫圖引擎、用 PyO3 給 Python 呼叫時,常見有兩種架構:
A. 你暴露的是「領域 API」(推薦)
- Rust 裡面用 petgraph 建圖
- 演算法需要的地方,用 rustworkx-core 提供的成熟函式補齊
- PyO3 暴露高階函式:例如
get_top_k_by_centrality(...)、expand_neighbors(...)
這樣 Python 端不需要知道你的圖結構,也不需要承擔 API 相容問題。
B. 你暴露的是「通用圖 API」(成本更高)
- 你需要在 Python <-> Rust 之間傳遞/映射圖資料
- 你要維護相容性(資料結構、序列化、版本)
除非你真的要做「可替換 NetworkX 的通用圖庫」,不然通常不划算。
常見誤解與踩坑
- 「rustworkx-core 可以無縫相容我現有的 petgraph 專案」:大多數情況是「很接近」,因為它就是建立在 petgraph 上並吃 petgraph trait,但仍要看你使用的 graph type 與 petgraph 版本範圍。
- 「多執行緒一定比較快」:並行化通常有 threshold(例如節點數)與 thread pool 的開銷;小圖可能反而更慢。把 parallel threshold 當成可調參數來看。
- 「我要 Leiden 社群偵測,所以一定選 rustworkx」:先確認你要的演算法是否已經提供;如果沒有,評估是要自己在 petgraph 上寫,還是直接貢獻/移植到 rustworkx-core 的路線。
參考連結
- rustworkx release notes:https://www.rustworkx.org/release_notes.html
- rustworkx benchmarks:https://www.rustworkx.org/benchmarks.html
- petgraph 文件:https://docs.rs/petgraph/
- rustworkx-core 文件:https://docs.rs/rustworkx-core/latest/rustworkx_core/
- ← Previous
把 GraphRAG 的「走圖」落實:graph.pkl 真遍歷、Local Search 合併擴展、Chat 支援 graph_hops - Next →
把 GraphRAG 想成全自動 Logseq/Roam:從雙向連結到社群摘要與走圖檢索