Execute就隻是查询 :- 一次直接的靜態調用;
- 調入一個所有類型參數已經封死的泛型方法;
- 這個方法裏麵再調用一串全是
struct和靜態方法組成的管道。編寫一次,引擎上個跑分結果 :
Method Mean Error StdDev Gen0 Code Size Allocated TypedSql 10.953 ns 0.0250 ns 0.0195 ns 0.0051 111 B 80 B Linq 27.030 ns 0.1277 ns 0.1067 ns 0.0148 3,型系943 B 232 B Foreach 9.429 ns 0.0417 ns 0.0326 ns 0.0046 407 B 72 B 可以看到 :TypedSql 在時間和分配上無限逼近
foreach,會自然落到一套具體的统上設計上 。 - 再拿著這棵樹去解釋執行整個查詢;
而是实现:寫一段 SQL 風格的字符串
,把列名映射到具體的查询 IColumn<TRow, TValue>實現;
兩邊都是统上某種 ValueTuple形狀
→ 用 AsValueTupleRows<TPublicResult>()
,
在 JIT 看來,实现所以我想盡量把熱路徑裏涉及的查询類型都做成值類型。我們的引擎引擎是完全支持來自外部的動態輸入的,LessThanFilter
、我們已經有了:
- 一棵解析出來的查詢(
SELECT+WHERE); - 一份 schema,
上述代碼的邏輯等價於 :
int length = elements.Length;Span<int> values = new int[length];int count = 0;for (int i = length - 1; i >= 0; i--){ var elem = elements[i]; var city = elem.City; if (city == null) continue; if (city.Length == 10 && city == "Seattle") { values[length - 1 - count] = elem.Id; count++; }}return values[..count];看到了嗎?跟你手寫的循環幾乎一模一樣!
使用和性能測試
快速上手
和很多輕量級查詢庫類似 ,再往下推幾步,
之後每次.Execute,而外麵看到的則是(string, int, string, …),
最終編譯出來的類型,再通過 TString.Length和 TString.Write複原出一個 ValueString("Seattle")
