即使在非常简单的情况下,我也要等到Coq完成其计算。
我了解“异步和并行的证明处理”,但是我想我的代码具有固有的弊端,因此我想对证明/证明样式的最佳实践获得一些参考或建议。例如:
尝试使用定义而不是定理,
使用编译器。使用并行处理。使用更好的硬件。
不要使用占位符,填写每个参数,例如(@functionname var1 ... varn)
用分号(;)代替句点(。)
使用“部分”中的“定义”代替“ set(f:= term)”要快得多。在证明中。(可能是因为每个“设置”都有额外的打印时间。甚至要检查是否为空。)
如何加快Coq?(如果我在上面的项目中有错误,请说。它们是根据我的实践得出的。)
什么是计算的最关键阶段以及如何使用它们?
圣杯是分析您的代码并优化热点。在勒柯克> = 8.6,你可以Set Ltac Profiling.和Reset Ltac Profile.和Show Ltac Profile.对个人资料的战术。如果您coqc使用-time参数进行调用,您将获得逐行计时信息。有点sed技巧可以为您分类信息:
coqc -time foo.v | sed s'/^\(.*\) \([0-9\.]\+ secs.*\)$/\2 \1/g' | sort -h
Run Code Online (Sandbox Code Playgroud)
在Coq> = 8.8中,您可以Set NativeCompute Profiling分析本机计算(例如Eval native_compute in (slow program here))。这将产生可perf report在GNU / Linux上可视化的痕迹。有关更多信息,请参见此错误报告。
如果遇到其他瓶颈,您要么必须擅长猜测,要么说服开发人员添加更多性能分析工具,分析正在运行的coq二进制文件,或者说服开发人员值得花时间为您分析代码。(当速度变慢指向Coq中的效率错误时,有时我可以让Pierre-MariePédrot来分析我的代码。)
一种有用的做法是始终在每次提交时都对代码进行概要分析。在Coq> = 8.7中,有Makefiletarget make-pretty-timed-before,make-pretty-timed-after和,print-pretty-timed-diff用于获得存储库两个状态之间每个文件编译时间差异的排序表。你可以得到每行信息有make TIMING=before,make TIMING=after,make all.timing.diff。
您可能也有兴趣查看Coq中实施绩效类别理论库的经验(此处有更多媒体),并且可能还有介绍该论文的幻灯片(pdf)(带有演示者注释的pptx)。
虽然您提到的大多数内容都无关紧要,但Coq在许多地方可能会变慢。依次检查您的:
Theorem并且Definition是同义词,唯一的区别是Definition支持:=和Theorem不支持。make -j。make)。让我知道您是否进行测试,否则发现其他问题。set本身不会因打印速度慢,而是因为它试图找到术语中所有出现的你的目标(愣神,最多有所下降(β-丝毫的事实?我不记得),而不是直到句法平等),并用新的假设取代它们。如果您不需要这种行为,请使用pose而不是set。此外,较大的上下文变量可能会降低取决于上下文大小的策略,这就是为什么Definition在各节中更快的原因。关于我遇到的事情的其他想法:
End Section(有时是慢速Defined)通常是由重新哈希处理问题引起的。要解决此问题,请双手合十祈祷。(或成为一名Coq开发人员并修复Coq。)fix具有大身体的裸露物体时非常慢(也许仅在存在β-碘-ζ-还原酶的情况下?)。解决方法是将主体提取到单独的定义中。例如,而不是写作定点长度A(ls:列表A):nat:= 与ls匹配 | 零=> 0 | 缺点_ xs => S(长度_ xs) 结束。
你可以写
定义length_step
(长度:全部A,列表A-> nat)
A(ls:清单A)
:nat
:=匹配ls与
| 零=> 0
| 缺点_ xs => S(长度_ xs)
结束。
定点长度A(ls:列表A):nat
:= length_step长度A ls。
let x := ... in ...语句,这很容易导致指数定义的内部化时间。simpl 总体来说很慢我可能会稍后再添加更多内容(并随时在评论中提出建议供我添加),但这是一个不错的开始。