推薦一個開源庫,其功能已經完全包含LINQ的所有方法,完全可以替代Linq。而且其有更高的性能和低內存占用的特點。
?
01
項目簡介
ZLinq 是一個由 Cysharp 團隊開發的開源項目,目標是為所有 .NET 平臺和 Unity 提供零分配的 LINQ 實現。它通過利用 Span 和 SIMD 技術,優化了 LINQ 的性能,同時提供了對樹形結構(如文件系統、JSON、游戲對象等)的查詢支持。
通過一行代碼,調用AsValueEnumerable() 方法,用戶可以將任何Linq轉換為 ZLinq。
using ZLinq;
var seq = source
.AsValueEnumerable() // 添加此代碼
.Where(x => x % 2 == 0)
.Select(x => x * 3);
02
核心特征
零分配 LINQ
傳統的 LINQ 實現雖然強大,但在處理大量數據時可能會因為頻繁的內存分配而導致性能瓶頸。ZLinq 通過結構體(struct)的方式實現可枚舉集合,避免了傳統 LINQ 中由于頻繁創建對象而導致的內存分配問題。
對 Span 的支持
ZLinq 充分利用了 .NET 9/C# 13 中引入的 allows ref struct 特性,支持對 Span 的操作。這意味著用戶可以在支持該特性的環境中,對 Span 類型進行高效的 LINQ 查詢操作。
LINQ to SIMD
ZLinq 自動應用 SIMD(單指令多數據)優化,以提升性能。用戶可以通過自定義方式進一步優化 SIMD 的使用,以滿足特定需求。
LINQ to Tree
ZLinq 擴展了 LINQ 的概念,使其能夠應用于樹形結構的查詢。它提供了類似 LINQ to XML 的軸操作(如 Ancestors、Children、Descendants、BeforeSelf 和 AfterSelf),可以對文件系統、JSON、Unity 的 GameObject 等樹形結構進行查詢。
03
入門指南
1、AsValueEnumerable(),即可使用 ZLinq 的零分配 LINQ。using ZLinq;
var source = new int[] { 1, 2, 3, 4, 5 };
// 調用 AsValueEnumerable 以應用 ZLinq
var seq1 = source.AsValueEnumerable().Where(x => x % 2 == 0);
// 也可以應用于 Span(僅在支持 allows ref struct 的 .NET 9/C# 13 環境中)
Span<int> span = stackalloc int[5] { 1, 2, 3, 4, 5 };
var seq2 = span.AsValueEnumerable().Select(x => x * x);
LINQ to XML 將圍繞軸進行查詢的概念引入到了 C# 中。即使你不使用 XML,類似的 API 也被納入了 Roslyn,并有效地用于探索語法樹。ZLinq 擴展了這一概念,使其適用于任何可以被視為樹形結構的對象,允許應用 Ancestors、Children、Descendants、BeforeSelf 和 AfterSelf。具體來說,通過定義一個實現了以下接口的結構體,即可使其可迭代:public interface ITraverser<TTraverser, T> : IDisposable
where TTraverser : struct, ITraverser<TTraverser, T> // 自身
{
T Origin { get; }
TTraverser ConvertToTraverser(T next); // 用于 Descendants
bool TryGetHasChild(out bool hasChild); // 可選:優化 Descendants 的使用
bool TryGetChildCount(out int count); // 可選:優化 Children 的使用
bool TryGetParent(out T parent); // 用于 Ancestors
bool TryGetNextChild(out T child); // 用于 Children | Descendants
bool TryGetNextSibling(out T next); // 用于 AfterSelf
bool TryGetPreviousSibling(out T previous); // BeforeSelf
}
3、文件系統
//安裝依賴庫
dotnet add package ZLinq.FileSystem?
using ZLinq;
var root = new DirectoryInfo("C:\\Program Files (x86)\\Steam");
// FileSystemInfo(FileInfo/DirectoryInfo) 可以調用 `Ancestors`、`Children`、`Descendants`、`BeforeSelf`、`AfterSelf`
var allDlls = root
.Descendants()
.OfType(default(FileInfo)!)
.Where(x => x.Extension == ".dll");
var grouped = allDlls
.GroupBy(x => x.Name)
.Select(x => new { FileName = x.Key, Count = x.Count() })
.OrderByDescending(x => x.Count);
foreach (var item in grouped)
{
Console.WriteLine(item);
}
4、JSON(System.Text.Json)
//安裝依賴庫
dotnet add package ZLinq.Json
using ZLinq;
// System.Text.Json 的 JsonNode 是 LINQ to JSON 的目標(不是 JsonDocument/JsonElement)。
var json = JsonNode.Parse("""
{
"nesting": {
"level1": {
"description": "First level of nesting",
"value": 100,
"level2": {
"description": "Second level of nesting",
"flags": [true, false, true],
"level3": {
"description": "Third level of nesting",
"coordinates": {
"x": 10.5,
"y": 20.75,
"z": -5.0
},
"level4": {
"description": "Fourth level of nesting",
"metadata": {
"created": "2025-02-15T14:30:00Z",
"modified": null,
"version": 2.1
},
"level5": {
"description": "Fifth level of nesting",
"settings": {
"enabled": true,
"threshold": 0.85,
"options": ["fast", "accurate", "balanced"],
"config": {
"timeout": 30000,
"retries": 3,
"deepSetting": {
"algorithm": "advanced",
"parameters": [1, 1, 2, 3, 5, 8, 13]
}
}
}
}
}
}
}
}
}
}
""");
// JsonNode
var origin = json!["nesting"]!["level1"]!["level2"]!;
// JsonNode axis, Children, Descendants, Anestors, BeforeSelf, AfterSelf and ***Self.
foreach (var item in origin.Descendants().Select(x => x.Node).OfType<JsoArray>())
{
// [true, false, true], ["fast", "accurate", "balanced"], [1, 1, 2, 3, 5, 8, 13]
Console.WriteLine(item.ToJsonString(JsonSerializerOptions.Web));
}
04
項目地址
https://github.com/Cysharp/ZLinq
該文章在 2025/3/21 12:46:42 編輯過