2011-03-31 17 views
29

年前有人问why c# doesn't allow incremental compilation like Java。 El Skeet表示这是关于Java输出.class文件而不是程序集的。如何能有人做一个像Java一样的C#增量编译器?

既然它的2011和Mono编译器即服务这样的常识已经发布,那么需要做些什么才能为c#增加一个编译器呢?

编辑:大家敲打有关如何,这是没有问题的,这里离我挂线是从乔恩斯基特报价:

你是在暗示你永远不会发现自己在等待一个构建?即使15秒 秒?如果构建过程需要15秒钟,并且您希望在一小时内完成20次(我当然会这么做),这意味着我正在浪费5分钟时间。休息5分钟是一件事 - 这是一个很好的方式 放松等 - 但被持续15秒20次可以非常令人沮丧。它不够长,无法做任何有用的事情(除了 也许喝了一口酒),但它足以刺激。

我怀疑两个因素促成烦恼的水平,我觉得这 其他人显然不: 1)TDD真正依靠更快的周转 2)当与Java在Eclipse中工作,这样的延迟是非常罕见的

+0

可能是因为没有人真的需要它吗? – Andrey 2011-03-31 15:45:10

+0

人们需要它。相信你我。 – mcintyre321 2011-03-31 15:50:44

+0

为什么?请提供一个场景。我想不出任何...这可能意味着,我没有幻想;-) – 2011-03-31 15:52:34

回答

10

如果没有完成,那么只有一个原因:努力做到这一点比可能的好处更高。

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

这里是我的答案为什么没有人需要它。您可以将构成单个项目的类分布到多个程序集中并逐个编译它们。它实际上是渐进式编译,但并不像逐类渐进式编译那样精细。而当你的架构正确设计时,汇编级增量编译就足够了。

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

编辑2:我发现this interesting thread人们在讨论单向C#编译器的Incremental编译。这是相当旧的,但关键的解释可能是仍然有效:

乐兴和正常解析非常 快,只在代码被解析的 的大小依赖。语义 分析通常是最花时间 耗时的步骤为装载引用 组件和各地的庞大 元数据进行筛选,以解决符号和类型 是真正的编译器的肉, 还,新的“编译”的代码是 “附加”到这个元数据/ AST什么 增加解决 符号随时间的复杂性。首先在内存中完成的代码排列是 ,因此速度很快。 保存到磁盘很慢,但取决于 发出的代码大小。

对于渐进式编译,缓存 元,就会使一切非常 快,因为通常很少会被 从一个编辑改成其他的 。但gmcs将不得不 使 元数据/ AST的部分无效,不构成 的

编辑3:C#编译器有在1.0和1.1版/incremental选项,但它是removed:在1.0和1.1版的C#的发现

的/增量标志编译器现在被认为已经过时。

编辑4:米格尔奥德伊卡萨给出明确的答案(12)为什么单编译器将不增量:

有很多很多地方 GMCS只是没有设计在 上编辑和继续场景。

如果有人想使这个他们 论文题目,那就是我没意见,但 变化量都在太多的领域太 大。我不想 甚至想打扰他们。

我没有列出的东西的原因是 ,因为它们将在编译器 无处不在。当你试用它们时,你肯定会遇到 ;-)

所以他认为这是一项比一个人的论文更大的任务。 Mono有更多更出色和更实际的任务。

+1

程序集如何防止按类逐步编译?在我看来,限制来自工具链的设计 - csc.exe输出完成的程序集,所以没有单独的链接程序。除了所付出的努力之外,还有什么可以阻止某人编写一个C#编译器来生成那些必须使用单独的链接器打包到程序集中的目标文件? – 2011-03-31 18:28:24

+0

@Sean U实际上有一个:al.exe(http://msdn.microsoft.com/en-us/library/c405shex(VS.80).aspx),但C#编译器不使用它。 – Andrey 2011-03-31 19:51:13

+1

当然,但正如你所说,Visual Studio附带的编译器都不依赖它;他们直接编译成程序集。我的问题是,是否有任何理由为什么csc.exe必须输出完整的程序集? – 2011-03-31 19:57:57