Background
我有一个代码生成器,可以在Ruust中生成长表达式,但编译器似乎没有很好地处理这一点.在这些示例中,为了简单起见,我使用常量/加法,但在实践中,我希望支持涉及变量和其他编程构造的更复杂的表达式.
Example
fn main() {
let _x = 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1
+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1
+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1
// ...
// 500 identical lines
// ...
+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1
+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1
;
}
当我试图编译它时,它崩溃了Segmentation fault (core dumped)
.(它的中间行较少,所以我认为这只是由于表达式的长度造成的崩溃.)
What I've tried
额外的括号
我试过在不同的地方放上括号.在每一行的开始和结束处添加括号可以停止崩溃,但需要一个小时来编译(还会因为操作顺序不同而更改语义):
fn main() {
let _x = 1+(1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)
+(1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)
+(1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)
// ...
// 8000 identical lines
// ...
+(1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)
+(1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)
;
}
♪Fasteval♪
Fsteval[https://docs.rs/♪Fasteval♪/latest/♪Fasteval♪/index.html]看起来可以更快地处理表达式,但只处理基本的变量操作和函数调用,因此不会处理表达式和更复杂的Ruust代码的混合.
变数
将每个表达式分解为许多生成的变量(每个二元运算符一个)也可以停止崩溃,但在变量数量上仍然有二次编译时间(例如,添加8000个数字需要9秒,添加16000个数字需要37秒).
将表达式分解为多个函数
这感觉应该可以工作,但在代码生成中要做的工作要多得多.
更改编译器
查看一下RUST编译器源代码,似乎是因为在进行树操作时对抽象语法 node 进行了大量克隆,所以速度很慢.感觉很多时候底层数据是不可变的,所以可以重用对现有不可变数据的引用,而不是复制所有树.然而,这感觉可能需要付出相当大的努力才能开始工作.
Question
有没有其他方法可以避免Ruust中大型表达式的编译时间很慢?(这是我的第一个Ruust程序,所以我可能遗漏了一些明显的东西,比如编译器标志或编写表达式的更惯用的方式).
更新
编译器的配置文件输出示例.
+-------------------------------------------------+-----------+-----------------+----------+------------+
| Item | Self time | % of total time | Time | Item count |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| typeck | 4.99s | 69.503 | 4.99s | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| thir_body | 1.73s | 24.112 | 1.73s | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| mir_built | 328.48ms | 4.572 | 2.06s | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| run_linker | 50.88ms | 0.708 | 50.88ms | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
...
更改为使用方括号和I32
正如Chayim Friedman在下面的回答中所建议的,使用1i32可以避免打字时间.配置文件现在大部分时间都花在thir_body中(来自3000行文件的配置文件):
+-------------------------------------------------+-----------+-----------------+----------+------------+
| Item | Self time | % of total time | Time | Item count |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| thir_body | 6.49s | 73.044 | 6.49s | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| mir_built | 1.02s | 11.506 | 7.51s | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| mir_borrowck | 402.33ms | 4.529 | 7.93s | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| mir_drops_elaborated_and_const_checked | 394.76ms | 4.444 | 394.80ms | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| typeck | 306.75ms | 3.453 | 312.72ms | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| optimized_mir | 118.45ms | 1.333 | 513.32ms | 5 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| run_linker | 52.22ms | 0.588 | 52.22ms | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+