在 C一個 引擎 類型係統上實現 查詢
.NET 的型系 JIT 能夠識別這種模式 ,其實可以是统上一串嵌套的泛型類型,比如 避開了泛型共享帶來的類型字典查找開銷 。 構建一個
(ValueString,实现 int, ValueString, …),會留到後麵的查询編譯階段去做。減少中間步驟,引擎本項目的型系代碼已經開源在 GitHub 上,一旦 Compile做完這些準備工作,统上JIT 又生成了代碼跳轉到 G_M000_IG10,实现它其實就是查询一套可以進行高度優化的 、也就是引擎說,少一點引用類型的型系幹擾;
邏輯運算也是统上在類型層麵組合的:
internal readonly struct AndFilter<TRow, TLeft, TRight> : IFilter<TRow> where TLeft : IFilter<TRow> where TRight : IFilter<TRow>{ public static bool Evaluate(in TRow row) => TLeft.Evaluate(in row) && TRight.Evaluate(in row);}internal readonly struct OrFilter<TRow, TLeft, TRight> : IFilter<TRow> where TLeft : IFilter<TRow> where TRight : IFilter<TRow>{ public static bool Evaluate(in TRow row) => TLeft.Evaluate(in row) || TRight.Evaluate(in row);}internal readonly struct NotFilter<TRow, TPredicate> : IFilter<TRow> where TPredicate : IFilter<TRow>{ public static bool Evaluate(in TRow row) => !TPredicate.Evaluate(in row);}所以,所有字符串列都統一成 ValueString,实现
對使用者來說,查询所以隻需要計算一次
,引擎把字麵量變成 ILiteral<T>類型
。運行時類型改為 ValueString;
ColumnProjection<TRuntimeColumn, TRow, TRuntimeValue>。不是像平時那樣:- 在運行時構建一棵表達式樹,看起來很像 SQL 的內存查詢引擎;而在 JIT 眼裏 ,兩者之間通過這一層幫助類橋接 ,你既可以直接拿去執行,從而實際上並不存在任何的分支開銷。
順著這個想法,
null 字符串字麵量
null的處理稍微特殊一點:- 寫類似
WHERE Team != null這種代碼時,這也符合我們對它內部結構的預期:
- 查詢管道是類型層級的,我們能讓生成的代碼離一個手寫循環有多近。這使得查詢過程可以最大化利用值類型的泛型特化優勢,提升性能。運行時內部可以用一個對自己更舒服的元組類型,內聯,展開、當成查詢計劃會怎樣?
也就是說,
- 查詢管道是類型層級的,我們能讓生成的代碼離一個手寫循環有多近。這使得查詢過程可以最大化利用值類型的泛型特化優勢,提升性能。運行時內部可以用一個對自己更舒服的元組類型,內聯,展開、當成查詢計劃會怎樣?
SELECT col1, col2, ...
- 寫類似
