【问题标题】:Roslyn Formatter.Format() takes too longRoslyn Formatter.Format() 耗时太长
【发布时间】:2018-02-27 21:39:11
【问题描述】:

我正在使用 Roslyn 生成大量代码(大约 60k 行)。 当我使用Formatter.Format() 格式化空白时,问题就来了。实际格式化花费的时间太长 (~60k lines in ~200s)。

使用的代码。

public string GenerateCode()
{
    var workspace = new AdhocWorkspace();

    OptionSet options = workspace.Options;
    options = options.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInMethods, true);
    options = options.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInProperties, true);

    CompilationUnitSyntax compilationUnit = CreateCompilationUnit();// this method builds the syntax tree.

    SyntaxNode formattedNode = Formatter.Format(compilationUnit, workspace, options);

    var sb = new StringBuilder();

    using (var writer = new StringWriter(sb))
    {
        formattedNode.WriteTo(writer);
    }

    return sb.ToString();
}

我意识到,人类可读的格式不是必需的(仍然会很好)。我停止格式化代码,但生成的代码实际上无法编译。那是因为某些关键字周围没有必要的空格。例如“publicstaticclassMyClass”。

我尝试了Formatter 的不同选项,但没有一个是足够的。 然后我正在寻找一种替代的“最小”格式化程序。据我所知,没有。

最后,我设法通过在标识符本身中添加额外的空格来解决这个问题。

var className = "MyClass";

SyntaxFactory.ClassDeclaration(" " + className)
    .AddModifiers(
        // Using explicit identifier with extra whitespace
        SF.Identifier(" public "),
        SF.Identifier(" static "));

        // Instead of the SyntaxKind enum
        //SF.Token(SyntaxKind.PublicKeyword),
        //SF.Token(SyntaxKind.StaticKeyword));

对于代码生成。

public string GenerateCode()
{
    var workspace = new AdhocWorkspace();

    CompilationUnitSyntax compilationUnit = CreateCompilationUnit(); // this method builds the syntax tree.

    var sb = new StringBuilder();
    using (var writer = new StringWriter(sb))
    {
        compilationUnit.WriteTo(writer);
    }

    return sb.ToString();
}

这样生成速度要快得多(~60k lines in ~2s 不是真正的行,因为它没有格式化,但它是相同数量的代码)。虽然这可行,但它似乎有点 hacky。另一种解决方案可能是创建一个替代Formatter,但这是我不想承担的任务。

有人想出更好的解决方案吗?有什么方法可以更有效地使用Formatter

注意:提供的时间测量包括构建语法树的时间和其他几个过程。在这两种情况下,格式化大约是测量时间的 98%。所以还是可以拿来比较的。

【问题讨论】:

  • Roslyn is open source。您是否考虑过分析代码以找出为什么格式化程序很慢?这可能是某种病态的分配模式,可以进行简单的修复。在那种情况下,每个人都会赢(而不是你为这种情况编写专用的格式化程序)。当然,它不必那么简单,但你至少有足够的背景材料来打开一个问题。

标签: c# .net code-generation roslyn


【解决方案1】:

您正在寻找的“最小格式化程序”是 .NormalizeWhitespace() 方法。

它不适合您打算由人类维护的代码,但我认为这应该不是问题,因为您正在处理一个 60k 行文件!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 2013-05-28
    • 2014-05-30
    • 2020-04-10
    相关资源
    最近更新 更多