怎么会有人像 Java 一样制作 c# 增量编译器?

发布于 2024-10-28 10:56:43 字数 646 浏览 7 评论 0原文

几年前有人问为什么c#不允许像Java 一样的增量编译。 El Skeet 表示,这与 Java 输出 .class 文件而不是程序集有关。

既然它的 2011 和诸如 Mono 编译器即服务之类的绝妙东西已经发布,那么需要做什么来为 C# 制作一个增量编译器呢?

编辑:对于每个人都在谈论这不是问题,这是我链接到的线程中乔恩·斯基特(Jon Skeet)的引用:

您是否建议您永远不会发现自己在等待构建?甚至15 秒?如果构建需要 15 秒,而您想要构建 20 次 一个小时(我当然是用TDD做的)这意味着我浪费了5个小时 分钟。休息 5 分钟是一回事 - 这是一个好方法 放松等 - 但 20 次 15 秒的停留可能会非常痛苦 令人沮丧。时间不够长,无法做任何有用的事情(除了 也许喝一杯)但时间已经足够长了。

我怀疑有两个因素导致了我的烦恼程度 其他人显然没有: 1) TDD 确实依赖于更快的周转 2) 在 Eclipse 中使用 Java 时,这种延迟非常罕见

Years ago someone asked why c# doesn't allow incremental compilation like Java. El Skeet said it is to do with Java outputting .class files rather than assemblies.

Now that its 2011 and groovy things like the Mono compiler-as-a-service have been released, what would need to be done to make an incremental compiler for c#?

edit: to everyone banging on about how this isn't a problem, here's a quote from Jon Skeet from the thread I linked to :

Are you suggesting you never find yourself waiting for a build? Even 15
seconds? If a build takes 15 seconds and you want to build 20 times in
an hour (which I certainly do with TDD) that means I'm wasting 5
minutes. Taking a 5 minute break is one thing - that's a good way of
relaxing etc - but being held up for 15 seconds 20 times can be very
frustrating. It's not long enough to do anything useful (other than
maybe sip a drink) but it's long enough to irritate.

I suspect two factors contribute the level of annoyance I feel which
others apparently don't:
1) TDD really relies on a faster turnaround
2) When working with Java in Eclipse, such delays are very rare

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

⒈起吃苦の倖褔 2024-11-04 10:56:43

如果没有做,那么只有一个原因:做这件事的努力高于可能获得的收益。

微软肯定不会这样做,因为成本太高:.net 代码存在于程序集中,没有人会更改它。是的,程序集会阻止逐类增量编译。没有人会停止使用组件。

这就是我的答案,为什么没有人需要它。您可以将构成单个项目的类分布在多个程序集中,然后一一编译它们。它实际上是增量编译,但不如逐类增量编译那么细粒度。当您的架构设计正确时,汇编级增量编译就足够了。

编辑:好的,我下载了 Mono C# 编译器来看看是否可以使其增量。我认为这不是很难。基本上它执行以下步骤:1)解析文件2)编译3)创建程序集。您可以在类型编译后挂钩某处,然后保存到某种中间文件中。然后仅重新编译更改的内容。所以这是可能的,但看起来这对于 Mono 团队来说并不是高优先级的问题。

编辑2:我发现这个有趣的线程,人们在其中讨论 Mono C# 编译器的增量编译。它相当旧,但关键解释可能仍然有效:

词法分析和解析通常非常重要
快速且仅取决于大小
正在解析的代码。语义学
分析通常是最多时间
加载引用的消耗步骤
组装并筛选巨大的
用于解析符号和类型的元数据
确实是编译器的核心,
另外,新的“编译”代码是
“附加”到此元数据/AST 什么
增加了解决问题的复杂性
随着时间的推移符号。代码的发射是
首先在内存中完成,所以速度很快。
保存到磁盘很慢,但取决于
发出的代码大小。

对于增量编译,缓存
元数据,将使一切变得非常
很快,通常情况下很少
从一份编译更改为
其他。但gmcs必须
仅使部分无效
元数据/AST,它没有构建什么
对于。

编辑3:C#编译器在v1.0和v1.1中有/incremental选项,但它是已删除

C# 编译器 1.0 和 1.1 版本中的 /incremental 标志现已被认为已过时。

编辑4:Miguel de Icaza给出了明确的答案(12) 为什么 Mono Compiler 不会是增量的:

还有很多很多地方
GMCS 的设计目的并不是为了
编辑并继续场景。

如果有人想将此作为他们的
论文主题,这对我来说很好,
但变化量太大
在很多领域都很大。我不
甚至想费心去枚举它们。

我没有列出事情的原因是
因为它们将无处不在
编译器。我确信你会遇到
一旦您尝试它们,它们就会立即出现;-)

所以他认为这是一项比一个人的论文更艰巨的任务。 Mono 还有更多突出且实际的任务。

If it was not done then there is only one reason for it: efforts to do it are higher than possible benefits.

Microsoft will definitely not do it because costs are too high: .net code lives in assemblies and no one will change it. And yes, assemblies prevent class-by-class incremental compilation. No one will stop using assemblies.

And here is my answer why no one needs it. You can distribute your classes that constitute single project among several assemblies and compile them one by one. It is actually incremental compilation but not as fine-grained as class-by-class incremental compilation. And when your architecture is properly designed assembly level incremental compilation is sufficient.

Edit: Okay, I downloaded Mono C# compiler to take a look it is possible to make it incremental. I think it is not very hard. Basically it does following steps: 1) Parse files 2) Compile 3) Create assembly. You could hook somewhere after types are compiled and save then into some sort of intermediate files. Then recompile only changed ones. So it is possible, but looks like it is not high-priority issue for Mono team.

Edit 2: I found this interesting thread where people discuss Incremental compilation for Mono C# compiler. It is rather old but key explanation might be still valid:

Lexing and parsing normally are very
fast and depend only on the size of
the code being parsed. Semantic
analysis is normally the most time
consuming step as loading referenced
assemblies and sifting around the huge
metadata to resolve symbols and types
is really the meat of the compiler,
also, new "compiled" code is
"appended" to this metadata/AST what
increases the complexity of resolving
symbols over time. Emission of code is
done in memory first so it is fast.
Saving to disk is slow but depends on
emitted code size.

For incremental compiling, caching the
metadata, would make everything very
fast, as normally very little would be
changed from one compilation to the
other. But gmcs would have to
invalidate only part of the
metadata/AST, what it wasn't built
for
.

Edit 3: C# compiler had /incremental option in v1.0 and v1.1, but it was removed:

The /incremental flag found in the 1.0 and 1.1 version of the C# compiler is now considered obsolete.

Edit 4: Miguel de Icaza gives clear answer (1, 2) why Mono Compiler will not be incremental:

There are many, many more places where
GMCS was just not designed to work on
an edit-and-continue scenario.

If someone wants to make this their
thesis subject, that is fine with me,
but the amount of changes are too
large in too many areas. I do not
even want to bother enumerating them.

The reason I did not list things is
because they will be everywhere in the
compiler. Am sure you will run into
them as soon as you try them out ;-)

So he considers it to be a task huger than for one man's thesis. And Mono has much more outstanding and actual tasks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文