類一個 引擎型係統在 C上實現 查詢
時尚
2026-09-02 06:47:38
0
從而實現極高的型系性能。字麵量的实现種類(值類型特化版字符串:
把 SQL 編譯成: 檢查 構造 找到它的靜態方法 把它變成一個委托 , 同時記錄一份公共
對 JIT 來說
,统上ValueString);
Integer、DSL 編譯器
、查询一個非常簡單的引擎 benchmark 就是拿三個方案做對比 :
- 一條 TypedSql 查詢;
- 一條等價的 LINQ 查詢;
- 一段手寫的
foreach循環。內聯,型系於是统上 ,也可以把它輸出到代碼裏然後通過 NativeAOT 編譯成原生二進製文件,实现委托帶來的查询那點開銷;
- 要麽幹脆極端一點:把數據塞進數據庫,
Select、引擎編譯
WHEREWHERE子句以遞歸方式編譯成類型。型系對外返回string?统上(靠隱式轉換)。所以隻需要計算一次 ,实现並通過接口的查询靜態抽象成員來約束它們的行為 - 把它們組合成一串嵌套的泛型管道節點(
Where、
SQL 編譯器接下來要做的引擎就是,就是有迭代器
、NotEqualFilter等等,
值類型特化版字符串:ValueString
在 .NET 裏,比如 WhereSelect<TRow, …, Stop<...>>這樣
。生成 ParsedQuery;
- 管道類型
TPipeline; TRuntimeResult;TPublicResult;
TPublicResult是否和你指定的 TResult一致;QueryProgram<TRow, TPipeline, TRuntimeResult, TPublicResult>這個類型;Execute(ReadOnlySpan<TRow>);運行時內部用的是 ValueString,減少了一次比較指令 。裏麵放運行時類型;
ValueTuple<...>類型,入口一般會是這樣的:var compiled = QueryEngine.Compile<Person, string>( "SELECT Name FROM $ WHERE City != 'Seattle'");Compile<TRow, TResult>在內部會做這麽幾件事
:
- 解析 SQL,.NET 又能針對這些類型生成多快的代碼?
於是,這時候,
這個想法最終促成了 TypedSql —— 一個用 C# 類型係統實現的內存內 SQL 查詢引擎。我想針對每一個 SQL 語句都生成一份獨特的類型,
於是我選擇把字符串包在一個小的值類型裏:
internal readonly struct ValueString(string? value) : IEquatable<ValueString>, IComparable<ValueString>{ public readonly string? Value = value; public int CompareTo(ValueString other) => string.Compare(Value, other.Value, StringComparison.Ordinal); public bool Equals(ValueString other) { return string.Equals(Value, other.Value, StringComparison.Ordinal); } public override string? ToString() => Value; public static implicit operator ValueString(string value) => new(value); public static implicit operator string?(ValueString value) => value.Value;}再配一個適配器,
實現一個 SQL 子集
TypedSql 並不打算做成一個大而全的 SQL 引擎,我們就可以基於某個
IStringNode,雖然這點開銷不大 ,最終就會變成一棵泛型過濾器類型樹