我有一个小型的测试框架。它执行以下循环:
生成一个小的Haskell源代码文件。
用
runhaskell
来执行。该程序会生成各种磁盘文件。处理刚生成的磁盘文件。
这个过程会重复数十次。结果发现,runhaskell
占据了该程序执行时间的绝大部分。
一方面,考虑到runhaskell
在2秒钟的墙上时间内能够从磁盘加载文件、对其进行记号化、解析、依赖分析、从磁盘加载20KB的文本、对所有这些内容进行记号和解析、执行完整的类型推断、检查类型、将其降级为核心,并链接到已编译的机器代码中并在解释器中执行,实际上非常令人印象深刻。另一方面,我仍然希望它运行得更快。;-)
编译测试器(运行上述循环的程序)会产生微小的性能差异。编译脚本链接的20KB库代码会产生更明显的改进。但每次调用runhaskell
仍然需要大约1秒钟的时间。
生成的Haskell文件只有略大于1KB,但实际上只有文件的一部分会发生变化。也许编译文件并使用GHC的-e
开关会更快?
或者说,重复创建和销毁许多OS进程的开销正在拖慢速度?每次调用runhaskell
可能会导致OS探索系统搜索路径,找到必要的二进制文件,将其加载到内存中(这肯定已经在磁盘缓存中了吧?),与任何DLL链接,并启动它。我是否可以(轻松地)保持一个GHC实例运行,而不是不断地创建和销毁OS进程?
最终,我想总有GHC API这个选择。但据我所知,那个API难以使用,文档极少,而且在每次GHC的小版本发布时都容易发生根本性的改变。我要完成的任务非常简单,所以我不想让事情变得比必要的更加复杂。
有什么建议吗?
更新: 切换到GHC -e
(即现在所有代码都被编译,除了要执行的一个表达式),没有明显的性能差异。目前看来很明显是由于操作系统的开销导致的。我在想是否可以从测试程序创建一个管道到GHCi,从而只利用一个操作系统进程...
ghc -O --make Main && ./program.exe
- Thomas Eding