性能反模式
识别和避免源生成器中的性能问题。
📋 文档信息
| 属性 | 值 |
|---|---|
| 难度 | 中级 |
| 阅读时间 | 25 分钟 |
| 前置知识 | 源生成器基础 |
| 相关文档 | 反模式索引、性能优化 |
反模式 1: 重复创建编译对象
❌ 错误做法
csharp
public void ProcessNodes(IEnumerable<SyntaxNode> nodes)
{
foreach (var node in nodes)
{
// 每次循环都创建新编译,性能极差
var compilation = CSharpCompilation.Create("Temp");
var semanticModel = compilation.GetSemanticModel(node.SyntaxTree);
// 处理...
}
}✅ 正确做法
csharp
private CSharpCompilation _compilation;
public void ProcessNodes(IEnumerable<SyntaxNode> nodes)
{
// 只创建一次编译
if (_compilation == null)
{
_compilation = CSharpCompilation.Create("Cached");
}
foreach (var node in nodes)
{
var semanticModel = _compilation.GetSemanticModel(node.SyntaxTree);
// 处理...
}
}反模式 2: 不必要的语法树遍历
❌ 错误做法
csharp
public void AnalyzeCode(SyntaxTree tree)
{
// 多次遍历同一棵树
var classes = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>();
var methods = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>();
var properties = tree.GetRoot().DescendantNodes().OfType<PropertyDeclarationSyntax>();
}✅ 正确做法
csharp
public void AnalyzeCode(SyntaxTree tree)
{
// 一次遍历收集所有需要的节点
var root = tree.GetRoot();
var classes = new List<ClassDeclarationSyntax>();
var methods = new List<MethodDeclarationSyntax>();
var properties = new List<PropertyDeclarationSyntax>();
foreach (var node in root.DescendantNodes())
{
switch (node)
{
case ClassDeclarationSyntax cls:
classes.Add(cls);
break;
case MethodDeclarationSyntax method:
methods.Add(method);
break;
case PropertyDeclarationSyntax prop:
properties.Add(prop);
break;
}
}
}反模式 3: 缺少缓存
❌ 错误做法
csharp
public string GetTypeName(ITypeSymbol type)
{
// 每次都重新计算
return type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
}✅ 正确做法
csharp
private readonly Dictionary<ITypeSymbol, string> _typeNameCache = new();
public string GetTypeName(ITypeSymbol type)
{
if (!_typeNameCache.TryGetValue(type, out var name))
{
name = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
_typeNameCache[type] = name;
}
return name;
}关键要点
- ✅ 缓存昂贵的对象(编译、语义模型)
- ✅ 减少语法树遍历次数
- ✅ 使用缓存存储计算结果
- ✅ 使用增量生成器提高性能
相关文档
最后更新: 2026-02-06